/**
 * Proveedor de Autenticación basado en Backend
 * Reemplaza FirebaseProvider
 */

'use client';

import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
import { apiClient } from '@/servicios/api-client';

export interface Usuario {
  id: number;
  correo: string;
  nombre: string;
  apellido: string;
  telefono?: string;
  rol: string;
  foto_perfil?: string;
  creado_en?: string;
}

export interface ContextoAutenticacion {
  usuario: Usuario | null;
  cargando: boolean;
  autenticado: boolean;
  error: string | null;
  iniciarSesion: (correo: string, contrasena: string) => Promise<void>;
  registrarse: (datos: RegistroData) => Promise<void>;
  cerrarSesion: () => void;
  refrescarUsuario: () => Promise<void>;
}

interface RegistroData {
  correo: string;
  contrasena: string;
  nombre: string;
  apellido: string;
  telefono?: string;
}

const AutorizacionContexto = createContext<ContextoAutenticacion | undefined>(undefined);

export function ProveedorAutenticacion({ children }: { children: ReactNode }) {
  const [usuario, setUsuario] = useState<Usuario | null>(null);
  const [cargando, setCargando] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Carga el usuario al montar
  useEffect(() => {
    const verificarToken = async () => {
      try {
        const token = localStorage.getItem('token');
        if (token) {
          apiClient.setToken(token);
          // Intenta obtener el usuario actual
          const usuarioData = await apiClient.get<Usuario>('/api/usuarios/perfil');
          setUsuario(usuarioData);
        }
      } catch (err) {
        // Token inválido o expirado - limpiar sin error
        const mensaje = err instanceof Error ? err.message : '';
        if (mensaje.includes('Token') || mensaje.includes('401') || mensaje.includes('403') || mensaje.includes('inválido') || mensaje.includes('expirado') || mensaje.includes('Error 401') || mensaje.includes('Error 403')) {
          // Token inválido - limpiar silenciosamente
          localStorage.removeItem('token');
          apiClient.clearToken();
        } else {
          console.error('Error al verificar token:', err);
        }
      } finally {
        setCargando(false);
      }
    };

    verificarToken();
  }, []);

  const iniciarSesion = useCallback(async (correo: string, contrasena: string) => {
    setError(null);
    try {
      setCargando(true);
      const respuesta = await apiClient.post<any>('/api/autenticacion/iniciar-sesion', {
        correo,
        contrasena,
      });

      const token = respuesta.token_acceso || respuesta.access_token;
      if (token) {
        apiClient.setToken(token);
        setUsuario(respuesta.usuario);
      }
    } catch (err) {
      const mensaje = err instanceof Error ? err.message : 'Error al iniciar sesión';
      setError(mensaje);
      throw err;
    } finally {
      setCargando(false);
    }
  }, []);

  const registrarse = useCallback(async (datos: RegistroData) => {
    setError(null);
    try {
      setCargando(true);
      const respuesta = await apiClient.post<any>('/api/autenticacion/registro', {
        correo: datos.correo,
        contrasena: datos.contrasena,
        nombre: datos.nombre,
        apellido: datos.apellido,
        telefono: datos.telefono,
      });

      const token = respuesta.token_acceso || respuesta.access_token;
      if (token) {
        apiClient.setToken(token);
        setUsuario(respuesta.usuario);
      }
    } catch (err) {
      const mensaje = err instanceof Error ? err.message : 'Error al registrarse';
      setError(mensaje);
      throw err;
    } finally {
      setCargando(false);
    }
  }, []);

  const cerrarSesion = useCallback(() => {
    apiClient.clearToken();
    setUsuario(null);
    localStorage.removeItem('token');
  }, []);

  const refrescarUsuario = useCallback(async () => {
    try {
      const usuarioActualizado = await apiClient.get<Usuario>('/api/usuarios/perfil');
      setUsuario(usuarioActualizado);
    } catch (err) {
      console.error('Error al refrescar usuario:', err);
    }
  }, []);

  const valor: ContextoAutenticacion = {
    usuario,
    cargando,
    autenticado: !!usuario,
    error,
    iniciarSesion,
    registrarse,
    cerrarSesion,
    refrescarUsuario,
  };

  return <AutorizacionContexto.Provider value={valor}>{children}</AutorizacionContexto.Provider>;
}

/**
 * Hook para acceder al contexto de autenticación
 */
export function useAutenticacion(): ContextoAutenticacion {
  const contexto = useContext(AutorizacionContexto);
  if (!contexto) {
    throw new Error('useAutenticacion debe ser usado dentro de ProveedorAutenticacion');
  }
  return contexto;
}
