const BlockedDevice = require('../models/BlockedDevice');
const User = require('../models/User');
const { blockUserDevice, unblockDevice, getBlockedDevices } = require('../middleware/deviceBlockMiddleware');

/**
 * Контроллер для управления блокировками устройств
 */

// @desc    Проверка блокировки устройства
// @route   POST /api/security/check-device
// @access  Public
const checkDeviceBlockStatus = async (req, res) => {
  try {
    const { fingerprint, deviceInfo } = req.body;
    const deviceFingerprint = fingerprint || req.deviceFingerprint;

    if (!deviceFingerprint) {
      return res.status(400).json({
        message: 'Device fingerprint требуется для проверки безопасности',
        code: 'DEVICE_FINGERPRINT_REQUIRED'
      });
    }

    console.log('[SECURITY] Проверка блокировки устройства:', deviceFingerprint.substring(0, 16) + '...');

    // Проверяем, заблокировано ли устройство
    const blockedDevice = await BlockedDevice.isDeviceBlocked(deviceFingerprint);
    
    if (blockedDevice) {
      console.log('[SECURITY] Устройство заблокировано:', blockedDevice._id);
      
      // Записываем попытку доступа
      await blockedDevice.addBypassAttempt({
        type: 'api_request',
        ipAddress: req.ip || req.connection.remoteAddress,
        userAgent: req.headers['user-agent']
      });

      return res.status(403).json({
        blocked: true,
        message: 'Доступ с данного устройства заблокирован',
        reason: blockedDevice.reason,
        blockedAt: blockedDevice.blockedAt,
        code: 'DEVICE_BLOCKED'
      });
    }

    // Обновляем информацию об устройстве
    if (deviceInfo) {
      // Можно сохранить информацию об активном устройстве для мониторинга
      console.log('[SECURITY] Активное устройство:', {
        fingerprint: deviceFingerprint.substring(0, 16) + '...',
        userAgent: deviceInfo.userAgent,
        platform: deviceInfo.platform
      });
    }

    res.json({
      blocked: false,
      message: 'Устройство не заблокировано'
    });

  } catch (error) {
    console.error('[SECURITY] Ошибка при проверке блокировки устройства:', error);
    res.status(500).json({
      message: 'Ошибка системы безопасности',
      code: 'SECURITY_CHECK_ERROR'
    });
  }
};

// @desc    Отчет о подозрительной активности
// @route   POST /api/security/report-suspicious
// @access  Private
const reportSuspiciousActivity = async (req, res) => {
  try {
    const { activities, deviceInfo } = req.body;
    const deviceFingerprint = req.deviceFingerprint;

    if (!deviceFingerprint) {
      return res.status(400).json({
        message: 'Device fingerprint требуется для отчета',
        code: 'DEVICE_FINGERPRINT_REQUIRED'
      });
    }

    console.log('[SECURITY] Получен отчет о подозрительной активности:', {
      fingerprint: deviceFingerprint.substring(0, 16) + '...',
      activitiesCount: activities?.length || 0,
      userId: req.user?._id
    });

    // Анализируем активность на предмет угроз
    const riskScore = calculateRiskScore(activities, deviceInfo);
    
    if (riskScore > 80) {
      console.warn('[SECURITY] Высокий уровень риска обнаружен:', riskScore);
      
      // Автоматическая блокировка при высоком риске
      if (req.user) {
        await blockUserDevice(
          req.user._id,
          req.user._id, // Автоматическая блокировка
          `Автоматическая блокировка: высокий уровень риска (${riskScore})`,
          deviceFingerprint
        );

        console.log('[SECURITY] Устройство автоматически заблокировано из-за высокого риска');
        
        return res.status(403).json({
          blocked: true,
          message: 'Устройство заблокировано из-за подозрительной активности',
          reason: 'Автоматическая блокировка системы безопасности',
          code: 'DEVICE_BLOCKED'
        });
      }
    }

    // Сохраняем отчет для анализа администраторами
    // Можно создать отдельную модель SuspiciousActivity или логировать
    console.log('[SECURITY] Отчет о подозрительной активности сохранен');

    res.json({
      message: 'Отчет получен и обработан',
      riskScore,
      action: riskScore > 80 ? 'blocked' : 'monitored'
    });

  } catch (error) {
    console.error('[SECURITY] Ошибка при обработке отчета о подозрительной активности:', error);
    res.status(500).json({
      message: 'Ошибка обработки отчета безопасности'
    });
  }
};

// @desc    Блокировка устройства (админ)
// @route   POST /api/admin/block-device
// @access  Private/Admin
const blockDevice = async (req, res) => {
  try {
    const { userId, deviceFingerprint, reason } = req.body;

    if (!userId || !deviceFingerprint || !reason) {
      return res.status(400).json({
        message: 'ID пользователя, device fingerprint и причина обязательны'
      });
    }

    // Проверяем, существует ли пользователь
    const user = await User.findById(userId);
    if (!user) {
      return res.status(404).json({
        message: 'Пользователь не найден'
      });
    }

    // Блокируем устройство
    const blockedDevice = await blockUserDevice(
      userId,
      req.user._id,
      reason,
      deviceFingerprint
    );

    console.log('[ADMIN] Устройство заблокировано администратором:', {
      deviceId: blockedDevice._id,
      userId,
      adminId: req.user._id,
      reason
    });

    res.status(201).json({
      message: 'Устройство успешно заблокировано',
      blockedDevice: {
        id: blockedDevice._id,
        deviceFingerprint: blockedDevice.deviceFingerprint,
        reason: blockedDevice.reason,
        blockedAt: blockedDevice.blockedAt
      }
    });

  } catch (error) {
    console.error('[ADMIN] Ошибка при блокировке устройства:', error);
    res.status(500).json({
      message: 'Ошибка при блокировке устройства',
      error: error.message
    });
  }
};

// @desc    Разблокировка устройства (админ)
// @route   POST /api/admin/unblock-device
// @access  Private/Admin
const unblockDeviceAdmin = async (req, res) => {
  try {
    const { deviceFingerprint, reason } = req.body;

    if (!deviceFingerprint) {
      return res.status(400).json({
        message: 'Device fingerprint обязателен'
      });
    }

    // Разблокируем устройство
    const device = await unblockDevice(
      deviceFingerprint,
      req.user._id,
      reason || 'Разблокировано администратором'
    );

    console.log('[ADMIN] Устройство разблокировано администратором:', {
      deviceId: device._id,
      adminId: req.user._id,
      reason
    });

    res.json({
      message: 'Устройство успешно разблокировано',
      device: {
        id: device._id,
        deviceFingerprint: device.deviceFingerprint,
        unblockedAt: new Date()
      }
    });

  } catch (error) {
    console.error('[ADMIN] Ошибка при разблокировке устройства:', error);
    res.status(500).json({
      message: 'Ошибка при разблокировке устройства',
      error: error.message
    });
  }
};

// @desc    Получение списка заблокированных устройств
// @route   GET /api/admin/blocked-devices
// @access  Private/Admin
const getBlockedDevicesList = async (req, res) => {
  try {
    const {
      page = 1,
      limit = 20,
      sortBy = 'blockedAt',
      sortOrder = 'desc',
      isActive = 'true',
      userId
    } = req.query;

    const filters = {
      page: parseInt(page),
      limit: parseInt(limit),
      sortBy,
      sortOrder,
      isActive: isActive === 'true',
      userId
    };

    const result = await getBlockedDevices(filters);

    console.log('[ADMIN] Запрос списка заблокированных устройств:', {
      adminId: req.user._id,
      filters,
      totalItems: result.pagination.totalItems
    });

    res.json({
      success: true,
      data: result.devices,
      pagination: result.pagination
    });

  } catch (error) {
    console.error('[ADMIN] Ошибка при получении списка заблокированных устройств:', error);
    res.status(500).json({
      message: 'Ошибка при получении списка заблокированных устройств',
      error: error.message
    });
  }
};

// @desc    Получение детальной информации о заблокированном устройстве
// @route   GET /api/admin/blocked-devices/:id
// @access  Private/Admin
const getBlockedDeviceDetails = async (req, res) => {
  try {
    const { id } = req.params;

    const device = await BlockedDevice.findById(id)
      .populate('blockedBy', 'name email')
      .populate('blockedUserId', 'name email')
      .populate('unblockRequests.requestedBy', 'name email')
      .populate('unblockRequests.reviewedBy', 'name email');

    if (!device) {
      return res.status(404).json({
        message: 'Заблокированное устройство не найдено'
      });
    }

    console.log('[ADMIN] Запрос деталей заблокированного устройства:', {
      deviceId: id,
      adminId: req.user._id
    });

    res.json({
      success: true,
      data: device
    });

  } catch (error) {
    console.error('[ADMIN] Ошибка при получении деталей заблокированного устройства:', error);
    res.status(500).json({
      message: 'Ошибка при получении информации об устройстве',
      error: error.message
    });
  }
};

/**
 * Вычисляет уровень риска на основе подозрительной активности
 */
function calculateRiskScore(activities, deviceInfo) {
  let score = 0;

  if (!activities || activities.length === 0) return 0;

  activities.forEach(activity => {
    switch (activity.type) {
      case 'fingerprint_change':
        score += 30; // Изменение fingerprint - высокий риск
        break;
      case 'multiple_login_attempts':
        score += 20;
        break;
      case 'suspicious_user_agent':
        score += 15;
        break;
      case 'rapid_requests':
        score += 10;
        break;
      default:
        score += 5;
    }
  });

  // Дополнительные факторы риска
  if (activities.length > 5) score += 10; // Много событий
  if (deviceInfo?.visitCount === 1) score += 15; // Новое устройство
  
  return Math.min(score, 100); // Максимум 100
}

module.exports = {
  checkDeviceBlockStatus,
  reportSuspiciousActivity,
  blockDevice,
  unblockDeviceAdmin,
  getBlockedDevicesList,
  getBlockedDeviceDetails
};