import { ref, computed } from 'vue';
import { AUTHENTIK_ENDPOINTS, AVATAR_CONFIG } from '../config/auth.js';
import { useToast } from './useToast.js';

/**
 * Composable para gestionar autenticación con Authentik
 * Adaptado de plantillaNuxtAuthentikProxy para Vue 3 vanilla
 */

// Estado global del usuario (singleton)
const authentikUser = ref(null);
const isLoading = ref(false);

// Flag para indicar si ya se intentó cargar desde window
let initialLoadAttempted = false;

export function useAuthentik() {
  const { toast } = useToast();

  /**
   * Obtener datos del usuario desde el backend o desde window.__AUTHENTIK_USER__
   * El backend inyecta esta información en el HTML al cargarlo
   */
  const fetchUserData = async (forceRefresh = false) => {
    // Primero intentar cargar desde window.__AUTHENTIK_USER__ (inyectado por el servidor)
    if (!initialLoadAttempted && typeof window !== 'undefined' && window.__AUTHENTIK_USER__) {
      initialLoadAttempted = true;
      const data = window.__AUTHENTIK_USER__;

      if (data.authenticated && data.user) {
        // Generar avatar URL usando UI Avatars
        const avatarName = encodeURIComponent(data.user.name || data.user.username);
        data.user.avatar = `${AVATAR_CONFIG.provider}?name=${avatarName}&background=${AVATAR_CONFIG.background}&size=${AVATAR_CONFIG.defaultSize}`;

        authentikUser.value = data.user;
      } else {
        authentikUser.value = null;
      }

      // Si window.__AUTHENTIK_USER__ indica que no hay autenticación, no hacer fetch adicional
      // a menos que se fuerce el refresh
      if (!forceRefresh && !data.authenticated) {
        return;
      }
    }

    // Solo hacer fetch si se fuerza o si no hay datos iniciales
    if (!forceRefresh && initialLoadAttempted && authentikUser.value === null) {
      return;
    }

    // Si no hay datos inyectados o se fuerza el refresh, hacer fetch al backend
    isLoading.value = true;
    try {
      const response = await fetch('/api/auth/status');

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();

      if (data.authenticated && data.user) {
        // Generar avatar URL usando UI Avatars
        const avatarName = encodeURIComponent(data.user.name || data.user.username);
        data.user.avatar = `${AVATAR_CONFIG.provider}?name=${avatarName}&background=${AVATAR_CONFIG.background}&size=${AVATAR_CONFIG.defaultSize}`;

        authentikUser.value = data.user;
      } else {
        authentikUser.value = null;
      }
    } catch (error) {
      console.error('Error fetching user data:', error);
      authentikUser.value = null;
    } finally {
      isLoading.value = false;
    }
  };

  /**
   * Cerrar sesión en Authentik
   * Redirige a la URL de invalidación de sesión
   */
  const logout = () => {
    window.location.href = AUTHENTIK_ENDPOINTS.logout;
  };

  /**
   * Ir al perfil de usuario en Authentik
   */
  const goToProfile = () => {
    window.open(AUTHENTIK_ENDPOINTS.profile, '_blank');
  };

  /**
   * Verificar el estado de la sesión contra el backend
   */
  const checkSessionStatus = async () => {
    // Verificar si está offline primero
    if (!navigator.onLine) {
      toast.info('Modo Offline', {
        description: 'No se puede validar sesión sin conexión',
      });
      return;
    }

    // Mostrar toast de "verificando..."
    toast.info('Verificando sesión...', {
      description: 'Consultando estado en Authentik',
    });

    try {
      const response = await fetch('/api/auth/status');

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();

      if (data.authenticated && data.user) {
        // Sesión activa en Authentik
        toast.success('Sesión Activa', {
          description: `Conectado como: ${data.user.name || data.user.username}`,
        });
      } else {
        // Sin sesión en Authentik
        toast.warning('Sin Sesión', {
          description: 'No hay sesión activa en Authentik. Recarga la página para autenticarte.',
        });
      }
    } catch (error) {
      // Verificar si está offline ahora (pudo desconectarse durante la petición)
      if (!navigator.onLine) {
        toast.info('Modo Offline', {
          description: 'No se puede validar sesión sin conexión',
        });
        return;
      }

      // Error de fetch generalmente indica CORS (redirección de Authentik)
      // Esto significa que la sesión expiró o no existe
      if (error instanceof TypeError && error.message.includes('fetch')) {
        toast.warning('Sesión Expirada', {
          description: 'Tu sesión ha expirado. Recarga la página para autenticarte nuevamente.',
        });
        console.warn('Session expired or CORS error:', error);
      } else {
        // Otro tipo de error
        toast.error('Error', {
          description: 'No se pudo verificar el estado de la sesión',
        });
        console.error('Error checking session status:', error);
      }
    }
  };

  /**
   * Verifica si el usuario pertenece a un grupo específico (frontend)
   * Lee los grupos desde el estado local
   */
  const hasGroup = (groupName) => {
    if (!authentikUser.value) return false;
    return authentikUser.value.groups.includes(groupName);
  };

  /**
   * Verifica si el usuario pertenece a un grupo específico (backend)
   * Consulta al servidor para validar contra Authentik
   */
  const checkGroupBackend = async (groupName) => {
    try {
      const response = await fetch('/api/auth/check-group', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ groupName })
      });
      const data = await response.json();
      return data.hasGroup || false;
    } catch (error) {
      console.error('Error checking group membership:', error);
      return false;
    }
  };

  return {
    user: computed(() => authentikUser.value),
    isAuthenticated: computed(() => !!authentikUser.value),
    isLoading: computed(() => isLoading.value),
    fetchUserData,
    logout,
    goToProfile,
    checkSessionStatus,
    hasGroup,
    checkGroupBackend,
  };
}
