import axios from 'axios';
import { getCurrentModuleAuth, clearModuleToken, getModuleFromPath, getSetorFromModule } from '@/utils/tokenManager';
import { decryptToken, validateTokenExpiration, maskTokenForLogging, secureLog, isDevelopment } from '@/utils/tokenSecurity';
import { generateCSRFToken, getCSRFToken, setCSRFToken } from '@/utils/tokenSecurity';

/**
 * Instância centralizada do Axios para todas as comunicações com o backend.
 * A base URL é configurada via variável de ambiente VITE_API_URL.
 * 
 * Exemplo de configuração no .env:
 * VITE_API_URL=https://dev.workspace.itguys.com.br/api
 */
const api = axios.create({
  baseURL: import.meta.env.VITE_API_URL || 'https://dev.workspace.itguys.com.br/api',
  headers: {
    'Content-Type': 'application/json',
  },
  timeout: 1200000, // 20 minutos (1200 segundos) para lidar com a lentidão do backend
  withCredentials: true, // Habilita envio de cookies (necessário para remember_2fa)
});

// Cache síncrono para tokens descriptografados (atualizado periodicamente)
let tokenCache = { token: null, setor: null, timestamp: 0 };
const CACHE_DURATION = 5000; // 5 segundos

/**
 * Obtém token e setor do cache ou tenta descriptografar síncronamente
 * Versão síncrona para uso no interceptor do axios
 */
const getCachedAuthSync = () => {
  const now = Date.now();
  
  // Se cache é válido, retorna
  if (tokenCache.token && (now - tokenCache.timestamp) < CACHE_DURATION) {
    return { token: tokenCache.token, setor: tokenCache.setor };
  }
  
  // Tenta obter token do módulo atual (versão síncrona com fallback)
  const module = getModuleFromPath();
  let token = null;
  let setor = null;
  
  if (module) {
    // Tenta obter token criptografado do módulo
    const encryptedToken = localStorage.getItem(`token_${module}`);
    if (encryptedToken && encryptedToken.startsWith('enc_')) {
      // Descriptografa de forma síncrona (pode ser lento, mas necessário)
      try {
        const obfuscated = encryptedToken.replace('enc_', '');
        const base64 = obfuscated.split('').reverse().join('');
        const decrypted = atob(base64);
        if (decrypted && validateTokenExpiration(decrypted)) {
          token = decrypted;
          setor = localStorage.getItem(`setor_${module}`) || getSetorFromModule(module);
        }
      } catch (e) {
        // Erro ao descriptografar, tenta fallback
      }
    } else if (encryptedToken && !encryptedToken.startsWith('enc_')) {
      // Token não criptografado (compatibilidade com tokens antigos)
      if (validateTokenExpiration(encryptedToken)) {
        token = encryptedToken;
        setor = localStorage.getItem(`setor_${module}`) || getSetorFromModule(module);
      }
    }
  }
  
  // Fallback: token global
  if (!token) {
    const globalEncrypted = localStorage.getItem('x-access-token');
    if (globalEncrypted) {
      if (globalEncrypted.startsWith('enc_')) {
        try {
          const obfuscated = globalEncrypted.replace('enc_', '');
          const base64 = obfuscated.split('').reverse().join('');
          const decrypted = atob(base64);
          if (decrypted && validateTokenExpiration(decrypted)) {
            token = decrypted;
            const module = getModuleFromPath();
            setor = module ? getSetorFromModule(module) : null;
          }
        } catch (e) {
          // Erro ao descriptografar
        }
      } else {
        // Token não criptografado (compatibilidade)
        if (validateTokenExpiration(globalEncrypted)) {
          token = globalEncrypted;
          const module = getModuleFromPath();
          setor = module ? getSetorFromModule(module) : null;
        }
      }
    }
  }
  
  // Atualiza cache
  if (token) {
    tokenCache = { token, setor, timestamp: Date.now() };
  }
  
  // Atualiza cache de forma assíncrona em background para próxima vez
  getCurrentModuleAuth().then(({ token: asyncToken, setor: asyncSetor }) => {
    if (asyncToken) {
      tokenCache = { token: asyncToken, setor: asyncSetor, timestamp: Date.now() };
    }
  }).catch(() => {
    // Ignora erros em background
  });
  
  return { token, setor };
};

// Interceptor para adicionar o token e setor em cada requisição
api.interceptors.request.use(
  async (config) => {
    // Não adiciona token em requisições de autenticação (Passo 1 e 2)
    // O backend espera x-access-token: null nessas requisições
    const isAuthRequest = config.url === '/auth' || config.url?.includes('/auth') || config.url === '/auth_pralog' || config.url === '/auth_oestepan';
    
    if (!isAuthRequest) {
      // Obtém token e setor de forma síncrona (interceptor precisa ser síncrono)
      const { token, setor } = getCachedAuthSync();
      
      if (token) {
        config.headers['x-access-token'] = token;
        
        // Adiciona setor via header (backend agora requer ambos)
        if (setor) {
          config.headers['x-setor'] = setor;
        }
        
        // Adiciona token CSRF para requisições mutantes
        const mutatingMethods = ['POST', 'PUT', 'PATCH', 'DELETE'];
        if (mutatingMethods.includes(config.method?.toUpperCase())) {
          let csrfToken = getCSRFToken();
          if (!csrfToken) {
            csrfToken = generateCSRFToken();
            setCSRFToken(csrfToken);
          }
          config.headers['x-csrf-token'] = csrfToken;
        }
      }
    } else {
      // Para requisições de autenticação, garante que os headers sejam removidos
      if (config.headers['x-access-token']) {
        delete config.headers['x-access-token'];
      }
      if (config.headers['x-setor']) {
        delete config.headers['x-setor'];
      }
      if (config.headers['x-csrf-token']) {
        delete config.headers['x-csrf-token'];
      }
    }
    
    // Log seguro apenas em desenvolvimento
    if (isDevelopment()) {
      secureLog('[API] Requisição', {
        method: config.method?.toUpperCase(),
        url: config.url,
        baseURL: config.baseURL,
        isAuthRequest,
        hasToken: !!token,
        hasSetor: !!setor,
        headers: Object.keys(config.headers || {})
      });
    }
    
    return config;
  },
  (error) => {
    if (isDevelopment()) {
      secureLog('[API] Erro no interceptor de request', { error: error.message });
    }
    return Promise.reject(error);
  }
);

// Interceptor para tratamento de erros de resposta
api.interceptors.response.use(
  (response) => {
    return response;
  },
  async (error) => {
    const currentPath = window.location.pathname;
    const isUnauthorized = error.response?.status === 401;
    const isForbidden = error.response?.status === 403;

    // Log apenas do erro necessário
    if (isDevelopment()) {
      secureLog('[API] Erro na resposta:', {
        status: error.response?.status,
        url: error.config?.url,
        method: error.config?.method?.toUpperCase(),
        data: error.response?.data
      });
    }

    // Tratamento de erro 401 (não autorizado) ou 403 (proibido): redireciona para login
    if (isUnauthorized || isForbidden) {
      // SEGURANÇA: Limpa TODO o localStorage (conforme solicitado para GR)
      // Isso força logout completo de todos os módulos
      localStorage.clear();
      
      // Limpar cache local do interceptor
      tokenCache = { token: null, setor: null, timestamp: 0 };

      // Redirecionar para login se não estiver já na página de login
      if (!currentPath.includes('/login') && !currentPath.includes('/auth/login')) {
        if (currentPath.includes('/plataforma/prafrot')) {
          window.location.href = '/plataforma/prafrot/login';
        } else if (currentPath.includes('/plataforma/financeiro-cnab')) {
          window.location.href = '/plataforma/auth/login-cnab';
        } else if (currentPath.includes('/plataforma/financeiro-v2')) {
          window.location.href = '/plataforma/auth/login-finance';
        } else if (currentPath.includes('/plataforma/fleet-v2')) {
          window.location.href = '/plataforma/auth/login';
        } else if (currentPath.includes('/plataforma/hr')) {
          window.location.href = '/plataforma/hr/login';
        } else if (currentPath.includes('/plataforma/fleet')) {
          window.location.href = '/plataforma/fleet/login';
        } else if (currentPath.includes('/plataforma/workspace')) {
          window.location.href = '/plataforma/workspace/login';
        } else if (currentPath.includes('/plataforma/gr')) {
          window.location.href = '/plataforma/gr/login';
        } else if (currentPath.includes('/plataforma/oest-pan')) {
          window.location.href = '/plataforma/oest-pan/login';
        } else {
          window.location.href = '/plataforma/auth/login';
        }
      }
    }

    return Promise.reject(error);
  }
);

export default api;
