import { ref, computed } from 'vue';
import api from './services/api'; // Наш API сервис
import router from './router';   // Vue Router для перенаправлений
import deviceSecurityService from './services/deviceSecurity'; // Система безопасности устройств

// Реактивные переменные для состояния пользователя и токена
const user = ref(null); // Данные пользователя (или null, если не вошел)
const token = ref(localStorage.getItem('userToken') || null); // Токен из localStorage или null

// Вычисляемое свойство для проверки, аутентифицирован ли пользователь
const isAuthenticated = computed(() => !!token.value && !!user.value);

// Функция для установки токена и данных пользователя
function setUserData(userData, userToken) {
  user.value = userData;
  token.value = userToken;
  localStorage.setItem('userToken', userToken); // Сохраняем токен в localStorage
  // Устанавливаем токен в заголовки Axios для последующих запросов (если не используется интерсептор)
  // Однако, наш интерсептор в api.js уже делает это, так что эта строка может быть избыточна,
  // но не повредит, если интерсептор по какой-то причине не сработает сразу.
  // api.defaults.headers.common['Authorization'] = `Bearer ${userToken}`;
}

// Функция для загрузки данных пользователя, если токен есть (например, при обновлении страницы)
async function fetchUser() {
  if (token.value) {
    try {
      console.log('Пытаемся загрузить пользователя с токеном из localStorage...');
      const response = await api.getMe(); // Используем наш API сервис
      
      console.log('Ответ от /auth/me:', response);
      
      // Проверяем структуру ответа
      if (!response.data) {
        throw new Error('Неверный формат ответа от сервера');
      }
      
      // Добавляем дополнительное логирование для отладки
      console.log('Получены данные пользователя:', response.data);
      console.log('Значение isAdmin в ответе:', response.data.isAdmin);
      
      // Сохраняем данные пользователя
      user.value = response.data;
      console.log('Пользователь успешно загружен:', user.value);
      console.log('isAuthenticated после загрузки пользователя:', isAuthenticated.value);
      console.log('Пользователь является администратором:', user.value.isAdmin ? 'Да' : 'Нет');
    } catch (error) {
      console.error('Не удалось загрузить пользователя по токену:', error.response ? error.response.data : error.message);
      // Если токен невалиден, очищаем его и данные пользователя
      await logout(); // Вызываем logout, чтобы очистить всё
    }
  } else {
    console.log('Токен не найден, пользователь не загружен.');
  }
}

// Функция входа
async function login(credentials) {
  try {
    console.log('Попытка входа с учетными данными:', { email: credentials.email });
    
    // Проверяем, не заблокировано ли устройство перед попыткой входа
    if (deviceSecurityService.isDeviceBlocked()) {
      throw new Error('Доступ с данного устройства заблокирован');
    }
    
    const response = await api.login(credentials);
    console.log('Ответ сервера при входе:', response);
    
    // Проверяем структуру данных в ответе
    if (!response.data || !response.data.token) {
      throw new Error('Неверный формат ответа от сервера: отсутствует токен');
    }
    
    // response.data должен содержать { _id, name, email, token, message }
    const { token: userToken, ...userData } = response.data; 
    
    // Убедимся, что userData содержит необходимые поля
    console.log('Данные пользователя для сохранения:', userData);
    
    // Перед сохранением данных
    console.log('isAuthenticated ДО входа:', isAuthenticated.value);
    console.log('Данные пользователя ДО входа:', user.value);
    
    // Сохраняем данные пользователя и токен
    setUserData(userData, userToken);
    
    // Записываем успешную попытку входа в систему безопасности
    if (deviceSecurityService.isInitialized()) {
      deviceSecurityService.recordLoginAttempt(true);
    }
    
    // После сохранения данных, но до перенаправления
    console.log('isAuthenticated ПОСЛЕ входа:', isAuthenticated.value);
    console.log('Данные пользователя ПОСЛЕ входа:', user.value);
    console.log('Токен ПОСЛЕ входа:', token.value);
    
    // Принудительное обновление состояния
    setTimeout(() => {
      console.log('isAuthenticated после таймаута:', isAuthenticated.value);
    }, 0);
    
    router.push('/'); // Перенаправляем на главную после входа
    return true;
  } catch (error) {
    console.error('Ошибка входа:', error.response ? error.response.data : error.message);
    
    // Записываем неудачную попытку входа в систему безопасности
    if (deviceSecurityService.isInitialized()) {
      deviceSecurityService.recordLoginAttempt(false);
      
      // Если слишком много неудачных попыток, записываем подозрительную активность
      if (error.response?.status === 429) {
        deviceSecurityService.recordSuspiciousActivity({
          type: 'rate_limit_exceeded',
          endpoint: '/auth/login',
          details: {
            email: credentials.email,
            userAgent: navigator.userAgent
          },
          timestamp: Date.now()
        });
      }
    }
    
    // Возвращаем сообщение об ошибке, чтобы отобразить в компоненте
    throw error.response ? error.response.data : new Error('Ошибка сети или сервера при входе');
  }
}

// Функция регистрации
async function register(userData) {
  try {
    const response = await api.register(userData);
    // response.data должен содержать { _id, name, email, token, message }
    const { token: userToken, ...newUserData } = response.data;
    setUserData(newUserData, userToken);
    // Обычно после регистрации мы либо сразу логиним пользователя, либо просим его войти.
    // Здесь мы его сразу "залогинили", сохранив токен и данные.
    router.push('/'); // Перенаправляем на главную (или на страницу подтверждения email, если бы она была)
    return true;
  } catch (error) {
    console.error('Ошибка регистрации:', error.response ? error.response.data : error.message);
    throw error.response ? error.response.data : new Error('Ошибка сети или сервера при регистрации');
  }
}

// Функция выхода
async function logout() {
  user.value = null;
  token.value = null;
  localStorage.removeItem('userToken');
  
  // Очищаем данные в системе безопасности устройств
  if (deviceSecurityService.isInitialized()) {
    deviceSecurityService.clearUserSession();
  }
  
  // Удаляем токен из заголовков Axios (если устанавливали его напрямую)
  // delete apiClient.defaults.headers.common['Authorization']; // apiClient не экспортируется из api.js напрямую для этого
  // Наш интерсептор запросов в api.js перестанет добавлять токен, так как его не будет в localStorage.
  router.push('/login'); // Перенаправляем на страницу входа
  console.log('Пользователь вышел из системы.');
}

// Функция обработки события блокировки аккаунта
function handleAccountBlocked(data) {
  console.log('[Auth] Экстренная обработка блокировки аккаунта:', data);

  try {
    // Создаем объект с информацией о блокировке
    const blockInfo = {
      blocked: true,
      message: data?.message || 'Ваш аккаунт был заблокирован администратором.',
      reason: data?.reason || 'Нарушение правил сервиса',
      timestamp: new Date().toISOString()
    };
    
    // Сохраняем информацию о блокировке в localStorage для отображения на странице логина
    localStorage.setItem('accountBlockedInfo', JSON.stringify(blockInfo));
    
    // Немедленно очищаем все данные пользователя
    console.log('[Auth] Очистка данных пользователя из-за блокировки');
    user.value = null;
    token.value = null;
    
    // Очистка localStorage - удаляем все ключи, которые могут содержать пользовательские данные
    localStorage.removeItem('userToken');
    localStorage.removeItem('userSettings');
    localStorage.removeItem('userPreferences');
    
    // Удаляем токены доступа для API запросов
    if (typeof api.setAuthToken === 'function') {
      api.setAuthToken(null);
      console.log('[Auth] Токен авторизации API удален');
    }
    
    // Пробуем отменить активные запросы
    if (typeof api.cancelActiveRequests === 'function') {
      api.cancelActiveRequests();
      console.log('[Auth] Активные запросы API отменены');
    }
    
    // Устанавливаем флаг в SessionStorage для индикации блокировки при перезагрузке страницы
    sessionStorage.setItem('forcedLogout', 'blocked');
    
    // Принудительный перенаправление на страницу логина с флагом блокировки
    console.log('[Auth] Перенаправление на страницу входа с параметром blocked=true');
    
    // Используем прямое изменение URL для полной перезагрузки страницы
    // Это гарантирует, что все состояния будут сброшены
    window.location.href = '/login?blocked=true&reason=' + encodeURIComponent(blockInfo.reason);
    
    // Не используем router.push, т.к. он не всегда работает корректно при критических ошибках
    // router.push({ name: 'Login', query: { blocked: 'true', reason: blockInfo.reason } });
    
    console.log('[Auth] Пользователь был разлогинен из-за блокировки аккаунта.');
    return true; // Возвращаем true, чтобы вызывающий код знал, что выход выполнен
  } catch (error) {
    console.error('[Auth] Критическая ошибка при обработке блокировки аккаунта:', error);
    
    // В случае любой ошибки, выполняем аварийный выход
    window.location.href = '/login?blocked=true&emergency=true';
    return false;
  }
}

// Функция обработки события разблокировки аккаунта
function handleAccountUnblocked(data) {
  console.log('Получено уведомление о разблокировке аккаунта:', data);
  
  // Удаляем информацию о блокировке, если она была сохранена
  localStorage.removeItem('accountBlockedInfo');
  
  // Показываем уведомление пользователю, если он сейчас в приложении
  // Можно использовать какую-то систему уведомлений в приложении
  // или просто логировать это событие
  
  // Если пользователь не залогинен, но его аккаунт был разблокирован,
  // можно показать соответствующее сообщение при следующем входе
  localStorage.setItem('accountUnblockedInfo', JSON.stringify({
    unblocked: true,
    message: data?.message || 'Ваш аккаунт был разблокирован.',
    timestamp: new Date().toISOString()
  }));
  
  console.log('Аккаунт пользователя разблокирован.');
}

// Функция обработки события блокировки устройства
function handleDeviceBlocked(data) {
  console.log('[Auth] Обработка блокировки устройства:', data);

  try {
    // Создаем объект с информацией о блокировке устройства
    const deviceBlockInfo = {
      blocked: true,
      message: data?.message || 'Доступ с данного устройства заблокирован.',
      reason: data?.reason || 'Подозрительная активность',
      timestamp: data?.blockedAt || new Date().toISOString(),
      deviceId: data?.deviceId || 'unknown'
    };
    
    // Сохраняем информацию о блокировке устройства
    localStorage.setItem('deviceBlockedInfo', JSON.stringify(deviceBlockInfo));
    
    // Обновляем состояние в сервисе безопасности устройств
    if (deviceSecurityService.isInitialized()) {
      deviceSecurityService.handleDeviceBlocked(data);
    }
    
    // Немедленно очищаем все данные пользователя
    console.log('[Auth] Очистка данных пользователя из-за блокировки устройства');
    user.value = null;
    token.value = null;
    localStorage.removeItem('userToken');
    
    // Устанавливаем флаг в SessionStorage
    sessionStorage.setItem('forcedLogout', 'device_blocked');
    
    // Перенаправляем на страницу входа с информацией о блокировке устройства
    console.log('[Auth] Перенаправление на страницу входа с параметром device blocked');
    
    window.location.href = '/login?blocked=true&type=device&reason=' + 
      encodeURIComponent(deviceBlockInfo.reason) + 
      '&message=' + encodeURIComponent(deviceBlockInfo.message);
    
    console.log('[Auth] Пользователь был разлогинен из-за блокировки устройства.');
    return true;
  } catch (error) {
    console.error('[Auth] Ошибка при обработке блокировки устройства:', error);
    window.location.href = '/login?blocked=true&type=device&emergency=true';
    return false;
  }
}

// Экспортируем то, что понадобится в компонентах
export function useAuth() {
  return {
    user,
    token,
    isAuthenticated,
    login,
    register,
    logout,
    fetchUser, // Эту функцию нужно будет вызвать при инициализации приложения
    handleAccountBlocked, // Добавляем функцию обработки блокировки аккаунта
    handleAccountUnblocked, // Добавляем функцию обработки разблокировки аккаунта
    handleDeviceBlocked // Добавляем функцию обработки блокировки устройства
  };
}