import DeviceFingerprint from '../utils/deviceFingerprint.js';
import { api } from './api.js';

/**
 * Сервис для работы с системой блокировки устройств
 */
class DeviceSecurityService {
  constructor() {
    this.deviceFingerprint = new DeviceFingerprint();
    this.currentFingerprint = null;
    this.isBlocked = false;
    this.initialized = false;
    this.suspiciousActivities = [];
    this.lastFingerprintCheck = null;
    this.checkInterval = null;
    
    // Настройки мониторинга
    this.config = {
      checkIntervalMs: 30000, // Проверка каждые 30 секунд
      maxSuspiciousActivities: 10,
      reportThreshold: 5, // Отправлять отчет после 5 подозрительных активностей
      fingerprintChangeThreshold: 0.1 // Порог изменения отпечатка (10%)
    };
  }

  /**
   * Инициализация сервиса безопасности
   */
  async initialize() {
    try {
      console.log('[DeviceSecurity] Инициализация сервиса безопасности устройств...');
      
      // Генерируем отпечаток устройства
      this.currentFingerprint = await this.deviceFingerprint.initialize();
      
      // Проверяем статус блокировки
      await this.checkDeviceBlockStatus();
      
      // Запускаем периодический мониторинг
      this.startMonitoring();
      
      this.initialized = true;
      console.log('[DeviceSecurity] Сервис безопасности инициализирован');
      
      return {
        fingerprint: this.currentFingerprint,
        isBlocked: this.isBlocked,
        initialized: true
      };
      
    } catch (error) {
      console.error('[DeviceSecurity] Ошибка при инициализации:', error);
      throw error;
    }
  }

  /**
   * Проверка статуса блокировки устройства
   */
  async checkDeviceBlockStatus() {
    try {
      const response = await api.post('/security/check-device', {
        fingerprint: this.currentFingerprint,
        deviceInfo: this.getDeviceInfo()
      });

      this.isBlocked = response.data.blocked || false;
      this.lastFingerprintCheck = Date.now();

      if (this.isBlocked) {
        console.warn('[DeviceSecurity] Устройство заблокировано:', response.data.reason);
        this.handleDeviceBlocked(response.data);
        return false;
      }

      console.log('[DeviceSecurity] Устройство не заблокировано');
      return true;

    } catch (error) {
      console.error('[DeviceSecurity] Ошибка при проверке блокировки:', error);
      
      // При ошибке API считаем устройство потенциально заблокированным
      if (error.response?.status === 403) {
        this.isBlocked = true;
        this.handleDeviceBlocked(error.response.data);
        return false;
      }
      
      return true; // При других ошибках разрешаем доступ
    }
  }

  /**
   * Получение информации об устройстве
   */
  getDeviceInfo() {
    return {
      userAgent: navigator.userAgent,
      platform: navigator.platform,
      language: navigator.language,
      screenResolution: `${screen.width}x${screen.height}`,
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
      timestamp: Date.now(),
      visitCount: this.getVisitCount()
    };
  }

  /**
   * Получение количества посещений (из localStorage)
   */
  getVisitCount() {
    try {
      const visits = localStorage.getItem('device_visits');
      const count = visits ? parseInt(visits) + 1 : 1;
      localStorage.setItem('device_visits', count.toString());
      return count;
    } catch (e) {
      return 1;
    }
  }

  /**
   * Запуск периодического мониторинга
   */
  startMonitoring() {
    if (this.checkInterval) {
      clearInterval(this.checkInterval);
    }

    this.checkInterval = setInterval(async () => {
      try {
        await this.performSecurityCheck();
      } catch (error) {
        console.error('[DeviceSecurity] Ошибка при периодической проверке:', error);
      }
    }, this.config.checkIntervalMs);

    console.log('[DeviceSecurity] Мониторинг запущен');
  }

  /**
   * Остановка мониторинга
   */
  stopMonitoring() {
    if (this.checkInterval) {
      clearInterval(this.checkInterval);
      this.checkInterval = null;
      console.log('[DeviceSecurity] Мониторинг остановлен');
    }
  }

  /**
   * Выполнение периодической проверки безопасности
   */
  async performSecurityCheck() {
    try {
      // Проверяем, не изменился ли отпечаток устройства
      await this.checkFingerprintChanges();
      
      // Проверяем статус блокировки
      await this.checkDeviceBlockStatus();
      
      // Отправляем отчет о подозрительных активностях, если накопилось достаточно
      if (this.suspiciousActivities.length >= this.config.reportThreshold) {
        await this.reportSuspiciousActivity();
      }
      
    } catch (error) {
      console.error('[DeviceSecurity] Ошибка при периодической проверке:', error);
    }
  }

  /**
   * Проверка изменений отпечатка устройства
   */
  async checkFingerprintChanges() {
    try {
      const newFingerprint = await this.deviceFingerprint.refresh();
      
      if (newFingerprint !== this.currentFingerprint) {
        console.warn('[DeviceSecurity] Обнаружено изменение отпечатка устройства');
        
        this.recordSuspiciousActivity({
          type: 'fingerprint_change',
          oldFingerprint: this.currentFingerprint.substring(0, 16) + '...',
          newFingerprint: newFingerprint.substring(0, 16) + '...',
          timestamp: Date.now()
        });
        
        this.currentFingerprint = newFingerprint;
      }
      
    } catch (error) {
      console.error('[DeviceSecurity] Ошибка при проверке изменений отпечатка:', error);
    }
  }

  /**
   * Запись подозрительной активности
   */
  recordSuspiciousActivity(activity) {
    this.suspiciousActivities.push({
      ...activity,
      id: Date.now() + Math.random(),
      recorded: new Date().toISOString()
    });

    // Ограничиваем размер массива
    if (this.suspiciousActivities.length > this.config.maxSuspiciousActivities) {
      this.suspiciousActivities = this.suspiciousActivities.slice(-this.config.maxSuspiciousActivities);
    }

    console.warn('[DeviceSecurity] Зафиксирована подозрительная активность:', activity.type);
  }

  /**
   * Отправка отчета о подозрительных активностях
   */
  async reportSuspiciousActivity() {
    try {
      if (this.suspiciousActivities.length === 0) return;

      console.log('[DeviceSecurity] Отправка отчета о подозрительных активностях...');
      
      const response = await api.post('/security/report-suspicious', {
        activities: this.suspiciousActivities,
        deviceInfo: this.getDeviceInfo(),
        fingerprint: this.currentFingerprint
      });

      // Если устройство было заблокировано автоматически
      if (response.data.blocked) {
        this.isBlocked = true;
        this.handleDeviceBlocked(response.data);
      }

      // Очищаем отправленные активности
      this.suspiciousActivities = [];
      
      console.log('[DeviceSecurity] Отчет отправлен, статус:', response.data.action);
      
    } catch (error) {
      console.error('[DeviceSecurity] Ошибка при отправке отчета:', error);
      
      if (error.response?.status === 403) {
        this.isBlocked = true;
        this.handleDeviceBlocked(error.response.data);
      }
    }
  }

  /**
   * Обработка блокировки устройства
   */
  handleDeviceBlocked(blockInfo) {
    console.error('[DeviceSecurity] Устройство заблокировано:', blockInfo);
    
    // Останавливаем мониторинг
    this.stopMonitoring();
    
    // Очищаем локальные данные
    this.clearLocalData();
    
    // Показываем уведомление пользователю
    this.showBlockedNotification(blockInfo);
    
    // Перенаправляем на страницу блокировки или выходим
    this.redirectToBlockedPage(blockInfo);
  }

  /**
   * Очистка локальных данных при блокировке
   */
  clearLocalData() {
    try {
      // Очищаем localStorage (кроме critical данных)
      const keysToKeep = ['device_visits'];
      const allKeys = Object.keys(localStorage);
      
      allKeys.forEach(key => {
        if (!keysToKeep.includes(key)) {
          localStorage.removeItem(key);
        }
      });
      
      // Очищаем sessionStorage
      sessionStorage.clear();
      
      console.log('[DeviceSecurity] Локальные данные очищены');
      
    } catch (error) {
      console.error('[DeviceSecurity] Ошибка при очистке данных:', error);
    }
  }

  /**
   * Показ уведомления о блокировке
   */
  showBlockedNotification(blockInfo) {
    const message = blockInfo.message || 'Доступ с данного устройства заблокирован';
    const reason = blockInfo.reason || 'Нарушение правил безопасности';
    
    // Используем встроенное API уведомлений браузера, если доступно
    if ('Notification' in window && Notification.permission === 'granted') {
      new Notification('Устройство заблокировано', {
        body: message,
        icon: '/pwa-192x192.png'
      });
    }
    
    // Также показываем alert для гарантии
    alert(`Устройство заблокировано\n\nПричина: ${reason}\n\n${message}`);
  }

  /**
   * Перенаправление на страницу блокировки
   */
  redirectToBlockedPage(blockInfo) {
    // Создаем URL с информацией о блокировке
    const params = new URLSearchParams({
      reason: blockInfo.reason || 'security_violation',
      code: blockInfo.code || 'DEVICE_BLOCKED',
      blocked_at: blockInfo.blockedAt || new Date().toISOString()
    });
    
    // Перенаправляем на страницу блокировки
    window.location.href = `/blocked?${params.toString()}`;
  }

  /**
   * Мониторинг множественных попыток входа
   */
  recordLoginAttempt(success) {
    const timestamp = Date.now();
    const attempts = this.getRecentAttempts();
    
    attempts.push({ timestamp, success });
    
    // Сохраняем последние 10 попыток
    const recentAttempts = attempts.filter(a => timestamp - a.timestamp < 300000); // 5 минут
    localStorage.setItem('login_attempts', JSON.stringify(recentAttempts));
    
    // Проверяем на подозрительную активность
    const failedAttempts = recentAttempts.filter(a => !a.success);
    if (failedAttempts.length >= 3) {
      this.recordSuspiciousActivity({
        type: 'multiple_login_attempts',
        count: failedAttempts.length,
        timespan: '5 minutes',
        timestamp
      });
    }
  }

  /**
   * Получение недавних попыток входа
   */
  getRecentAttempts() {
    try {
      const attempts = localStorage.getItem('login_attempts');
      return attempts ? JSON.parse(attempts) : [];
    } catch (e) {
      return [];
    }
  }

  /**
   * Проверка инициализации
   */
  isInitialized() {
    return this.initialized;
  }

  /**
   * Получение текущего отпечатка
   */
  getCurrentFingerprint() {
    return this.currentFingerprint;
  }

  /**
   * Проверка блокировки
   */
  isDeviceBlocked() {
    return this.isBlocked;
  }

  /**
   * Получение компонентов отпечатка (для отладки)
   */
  getFingerprintComponents() {
    return this.deviceFingerprint.getComponents();
  }

  /**
   * Получение статистики подозрительных активностей
   */
  getSuspiciousActivitiesStats() {
    return {
      total: this.suspiciousActivities.length,
      activities: this.suspiciousActivities.slice(),
      lastCheck: this.lastFingerprintCheck
    };
  }

  /**
   * Очистка истории (для отладки)
   */
  clearHistory() {
    this.suspiciousActivities = [];
    localStorage.removeItem('login_attempts');
    console.log('[DeviceSecurity] История очищена');
  }

  /**
   * Деструктор
   */
  destroy() {
    this.stopMonitoring();
    this.suspiciousActivities = [];
    this.initialized = false;
    console.log('[DeviceSecurity] Сервис уничтожен');
  }
}

// Создаем единственный экземпляр сервиса
const deviceSecurityService = new DeviceSecurityService();

export default deviceSecurityService;