const express = require('express');
const router = express.Router();

/**
 * Middleware для проверки аутентификации оператора
 */
const authenticateOperator = (req, res, next) => {
  const operatorId = req.headers['x-operator-id'];
  
  if (!operatorId) {
    return res.status(401).json({ error: 'Operator ID required' });
  }
  
  const operator = req.app.locals.deviceManager.getOperator(operatorId);
  if (!operator || !operator.isConnected()) {
    return res.status(401).json({ error: 'Invalid or disconnected operator' });
  }
  
  req.operator = operator;
  next();
};

/**
 * Middleware для проверки разрешений
 */
const requirePermission = (permission) => {
  return (req, res, next) => {
    if (!req.operator.hasPermission(permission)) {
      return res.status(403).json({ error: `Permission '${permission}' required` });
    }
    next();
  };
};

/**
 * GET /api/operators/devices
 * Получение списка доступных устройств
 */
router.get('/devices', authenticateOperator, requirePermission('view_cameras'), (req, res) => {
  try {
    const { deviceManager } = req.app.locals;
    const devices = deviceManager.getAvailableDevicesForOperator(req.operator.operatorId);
    
    const devicesData = devices.map(device => device.getSummary());
    
    res.json({
      success: true,
      devices: devicesData,
      total: devicesData.length
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * GET /api/operators/devices/:deviceId
 * Получение информации о конкретном устройстве
 */
router.get('/devices/:deviceId', authenticateOperator, requirePermission('view_cameras'), (req, res) => {
  try {
    const { deviceManager } = req.app.locals;
    const device = deviceManager.getDevice(req.params.deviceId);
    
    if (!device) {
      return res.status(404).json({ error: 'Device not found' });
    }
    
    res.json({
      success: true,
      device: device.getSummary()
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * POST /api/operators/camera/request
 * Создание запроса на доступ к камере
 */
router.post('/camera/request', authenticateOperator, requirePermission('request_camera'), (req, res) => {
  try {
    const { deviceId, cameraType = 'back' } = req.body;
    
    if (!deviceId) {
      return res.status(400).json({ error: 'Device ID required' });
    }
    
    const { deviceManager, sessionManager, io } = req.app.locals;
    const device = deviceManager.getDevice(deviceId);
    
    if (!device) {
      return res.status(404).json({ error: 'Device not found' });
    }
    
    if (!device.canAcceptNewSession()) {
      return res.status(409).json({ error: 'Device is busy or unavailable' });
    }
    
    // Создаем сессию
    const session = sessionManager.createSession(deviceId, req.operator.operatorId, cameraType);
    
    // Отправляем запрос на Android устройство
    device.socket.emit('camera:request', {
      sessionId: session.sessionId,
      operatorId: req.operator.operatorId,
      cameraType
    });
    
    // Добавляем сессию к устройству и оператору
    device.addSession(session.sessionId);
    req.operator.addSession(session.sessionId);
    
    req.app.locals.logger.info(`Camera request created: ${session.sessionId}`, {
      deviceId,
      operatorId: req.operator.operatorId,
      cameraType
    });
    
    res.json({
      success: true,
      sessionId: session.sessionId,
      message: 'Camera request sent to device'
    });
    
  } catch (error) {
    req.app.locals.logger.error('Error creating camera request', error);
    res.status(500).json({ error: error.message });
  }
});

/**
 * POST /api/operators/camera/:sessionId/switch
 * Переключение типа камеры в активной сессии
 */
router.post('/camera/:sessionId/switch', authenticateOperator, requirePermission('request_camera'), (req, res) => {
  try {
    const { sessionId } = req.params;
    const { cameraType } = req.body;
    
    if (!cameraType) {
      return res.status(400).json({ error: 'Camera type required' });
    }
    
    const { sessionManager, deviceManager, io } = req.app.locals;
    const session = sessionManager.getSession(sessionId);
    
    if (!session) {
      return res.status(404).json({ error: 'Session not found' });
    }
    
    if (session.operatorId !== req.operator.operatorId) {
      return res.status(403).json({ error: 'Access denied to this session' });
    }
    
    if (session.status !== 'active') {
      return res.status(409).json({ error: 'Session is not active' });
    }
    
    const device = deviceManager.getDevice(session.deviceId);
    if (!device || !device.isConnected()) {
      return res.status(409).json({ error: 'Device not available' });
    }
    
    // Отправляем команду переключения камеры
    device.socket.emit('camera:switch', {
      sessionId,
      cameraType
    });
    
    // Обновляем сессию
    session.switchCamera(cameraType);
    
    req.app.locals.logger.info(`Camera switch requested: ${sessionId} -> ${cameraType}`);
    
    res.json({
      success: true,
      message: `Camera switch to ${cameraType} requested`
    });
    
  } catch (error) {
    req.app.locals.logger.error('Error switching camera', error);
    res.status(500).json({ error: error.message });
  }
});

/**
 * DELETE /api/operators/camera/:sessionId
 * Завершение сессии камеры
 */
router.delete('/camera/:sessionId', authenticateOperator, requirePermission('request_camera'), (req, res) => {
  try {
    const { sessionId } = req.params;
    
    const { sessionManager, deviceManager } = req.app.locals;
    const session = sessionManager.getSession(sessionId);
    
    if (!session) {
      return res.status(404).json({ error: 'Session not found' });
    }
    
    if (session.operatorId !== req.operator.operatorId) {
      return res.status(403).json({ error: 'Access denied to this session' });
    }
    
    const device = deviceManager.getDevice(session.deviceId);
    
    // Отправляем команду отключения (если устройство подключено)
    if (device && device.isConnected()) {
      device.socket.emit('camera:disconnect', { sessionId });
      device.removeSession(sessionId);
    }
    
    // Закрываем сессию
    sessionManager.closeSession(sessionId);
    req.operator.removeSession(sessionId);
    
    req.app.locals.logger.info(`Session terminated: ${sessionId}`);
    
    res.json({
      success: true,
      message: 'Session terminated'
    });
    
  } catch (error) {
    req.app.locals.logger.error('Error terminating session', error);
    res.status(500).json({ error: error.message });
  }
});

/**
 * GET /api/operators/sessions
 * Получение активных сессий оператора
 */
router.get('/sessions', authenticateOperator, (req, res) => {
  try {
    const { sessionManager } = req.app.locals;
    const sessions = sessionManager.getOperatorSessions(req.operator.operatorId);
    
    const sessionsData = sessions.map(session => session.getSummary());
    
    res.json({
      success: true,
      sessions: sessionsData,
      total: sessionsData.length
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * GET /api/operators/sessions/:sessionId
 * Получение детальной информации о сессии
 */
router.get('/sessions/:sessionId', authenticateOperator, (req, res) => {
  try {
    const { sessionId } = req.params;
    const { sessionManager } = req.app.locals;
    
    const session = sessionManager.getSession(sessionId);
    if (!session) {
      return res.status(404).json({ error: 'Session not found' });
    }
    
    if (session.operatorId !== req.operator.operatorId && !req.operator.hasPermission('admin')) {
      return res.status(403).json({ error: 'Access denied to this session' });
    }
    
    res.json({
      success: true,
      session: session.getFullInfo()
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * GET /api/operators/profile
 * Получение профиля текущего оператора
 */
router.get('/profile', authenticateOperator, (req, res) => {
  try {
    res.json({
      success: true,
      operator: req.operator.getSummary()
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * POST /api/operators/ping/:deviceId
 * Проверка доступности устройства
 */
router.post('/ping/:deviceId', authenticateOperator, requirePermission('view_cameras'), (req, res) => {
  try {
    const { deviceId } = req.params;
    const { deviceManager } = req.app.locals;
    
    const device = deviceManager.getDevice(deviceId);
    if (!device || !device.isConnected()) {
      return res.status(404).json({ error: 'Device not found or disconnected' });
    }
    
    const pingStart = Date.now();
    
    // Отправляем ping и ждем pong
    device.socket.emit('ping', { timestamp: pingStart }, (response) => {
      const responseTime = Date.now() - pingStart;
      device.updateHealthCheck(responseTime);
      
      res.json({
        success: true,
        deviceId,
        responseTime,
        timestamp: new Date().toISOString()
      });
    });
    
    // Таймаут для ping
    setTimeout(() => {
      if (!res.headersSent) {
        device.recordError();
        res.status(408).json({ error: 'Device ping timeout' });
      }
    }, 5000);
    
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;