import { ref, computed } from 'vue'

// Estado global compartido para auth
const authChecked = ref(true) // Iniciamos como chequeado
const isAuthenticated = ref(true) // Asumimos autenticado al inicio (si la página cargó, es porque pasamos Authentik)
const isCheckingAuth = ref(false)
const lastCheckTime = ref(0)
const isOffline = ref(false) // Estado de conexión

// Estado de información del usuario
const userInfo = ref(null)

// Listener para cambios de autenticación desde otras tabs/ventanas
let visibilityChangeListener: (() => void) | null = null
let focusListener: (() => void) | null = null

export const useAuth = () => {
  // Detectar cambios en el estado de conexión
  if (import.meta.client) {
    const updateOnlineStatus = () => {
      const wasOffline = isOffline.value
      isOffline.value = !navigator.onLine

      if (wasOffline && !isOffline.value) {
        console.log('[Auth] Connection restored - back online')
      } else if (!wasOffline && isOffline.value) {
        console.log('[Auth] Connection lost - now offline')
      }
    }

    // Inicializar estado
    updateOnlineStatus()

    // Escuchar eventos de conexión
    window.addEventListener('online', updateOnlineStatus)
    window.addEventListener('offline', updateOnlineStatus)
  }

  const checkAuth = async (force = false) => {
    // Si estamos offline, no hacer requests
    if (isOffline.value && !force) {
      console.log('[Auth] Skipping check - offline')
      return
    }

    // Si ya sabemos que NO estamos autenticados, no hacer más requests
    // (evita loops innecesarios)
    if (!isAuthenticated.value && !force) {
      console.log('[Auth] Skipping check - already known to be unauthenticated')
      return
    }

    // Evitar chequeos duplicados (cache de 30 segundos)
    const now = Date.now()
    if (!force && isCheckingAuth.value) return
    if (!force && authChecked.value && now - lastCheckTime.value < 30000) {
      return
    }

    isCheckingAuth.value = true

    try {
      // Usar endpoint dedicado que lee headers de Authentik desde el servidor
      // Este endpoint tiene headers no-cache y verifica la sesión en tiempo real
      const response = await $fetch<{ authenticated: boolean; user: any | null; timestamp: string }>('/api/auth/status', {
        // No usar redirect: 'error' aquí porque queremos la respuesta del servidor
        // El endpoint responde con authenticated: false si no hay sesión
      })

      const wasAuthenticated = isAuthenticated.value
      isAuthenticated.value = response.authenticated
      authChecked.value = true
      lastCheckTime.value = now

      // Log cambios de estado
      if (wasAuthenticated !== isAuthenticated.value) {
        console.log('[Auth] Status changed:', isAuthenticated.value ? 'authenticated' : 'unauthenticated')
        if (response.user) {
          console.log('[Auth] User:', response.user.username)
        }
      }
    } catch (error: any) {
      console.warn('[Auth] Check failed:', error.message || error)

      // Verificar si estamos offline AHORA (pudo cambiar durante el request)
      if (!navigator.onLine) {
        console.log('[Auth] Offline detected - maintaining current auth state')
        isOffline.value = true
        // NO cambiar isAuthenticated cuando estamos offline
        // Mantener el último estado conocido
      } else {
        // Online pero el fetch falló = problema de autenticación
        const wasAuthenticated = isAuthenticated.value
        console.log('[Auth] Online but fetch failed - marking as unauthenticated')
        isAuthenticated.value = false
        authChecked.value = true

        if (wasAuthenticated) {
          console.log('[Auth] Status changed: authenticated → unauthenticated')
        }
      }

      lastCheckTime.value = now
    } finally {
      isCheckingAuth.value = false
    }
  }

  const triggerAuth = async () => {
    console.log('[Auth] Triggering authentication flow...')

    // Desregistrar el Service Worker temporalmente para evitar conflictos con Authentik
    if ('serviceWorker' in navigator) {
      try {
        const registrations = await navigator.serviceWorker.getRegistrations()
        console.log('[Auth] Unregistering Service Workers before auth...')
        await Promise.all(registrations.map(reg => reg.unregister()))
      } catch (error) {
        console.warn('[Auth] Could not unregister SW:', error)
      }
    }

    // Forzar navegación completa a la raíz
    // Authentik interceptará y redirigirá al login si no estamos autenticados
    console.log('[Auth] Forcing hard navigation to trigger Authentik...')
    window.location.href = window.location.origin + '/'
  }

  const fetchUserInfo = async () => {
    if (!isAuthenticated.value) {
      console.log('[Auth] Cannot fetch user info - not authenticated')
      return
    }

    try {
      const response = await $fetch<{ authenticated: boolean; user: any | null }>('/api/auth/status')
      if (response.authenticated && response.user) {
        userInfo.value = response.user
        console.log('[Auth] User info loaded:', response.user)
      } else {
        userInfo.value = null
      }
    } catch (error) {
      console.warn('[Auth] Failed to fetch user info:', error)
      userInfo.value = null
    }
  }

  const logout = async () => {
    console.log('[Auth] Logging out...')

    // Marcar como no autenticado y desregistrar SW
    await markUnauthenticated()

    // Limpiar información del usuario
    userInfo.value = null

    // Navegar directamente al servidor de Authentik para logout
    // Authentik tiene un flujo de invalidación por defecto que cierra la sesión
    console.log('[Auth] Navigating to Authentik logout...')
    window.location.href = 'https://authentik.nucleoriofrio.com/if/flow/default-invalidation-flow/'
  }

  const markUnauthenticated = async () => {
    // Helper para marcar como no autenticado (útil cuando detectamos 401/403)
    // IMPORTANTE: NO llamar esto si estamos offline, solo si hay un error real de auth

    // Si estamos offline, NO marcar como no autenticado
    if (isOffline.value || !navigator.onLine) {
      console.log('[Auth] Skipping markUnauthenticated - offline mode')
      return
    }

    console.log('[Auth] Marking as unauthenticated')
    isAuthenticated.value = false
    authChecked.value = true
    lastCheckTime.value = Date.now()

    // Desregistrar Service Worker para evitar conflictos con Authentik
    if ('serviceWorker' in navigator) {
      try {
        const registrations = await navigator.serviceWorker.getRegistrations()
        if (registrations.length > 0) {
          console.log('[Auth] Unregistering Service Worker due to auth loss...')
          await Promise.all(registrations.map(reg => reg.unregister()))
          console.log('[Auth] Service Worker unregistered - page will need reload for re-auth')
        }
      } catch (error) {
        console.warn('[Auth] Could not unregister SW:', error)
      }
    }
  }

  const setupVisibilityListener = () => {
    // DESHABILITADO: Los listeners causan problemas con Authentik
    // Cuando no estamos autenticados, los listeners intentan hacer fetch
    // y Authentik redirige, causando errores de CORS
    // En su lugar, confiamos en que el usuario haga click en "Reautenticar"
    console.log('[Auth] Visibility listeners disabled to avoid conflicts with Authentik')
    return

    /* CÓDIGO DESHABILITADO
    // Re-chequea auth cuando la pestaña vuelve a ser visible
    // (útil si el usuario se autentica en otra pestaña)
    if (typeof document !== 'undefined' && !visibilityChangeListener) {
      visibilityChangeListener = () => {
        if (!document.hidden && isAuthenticated.value) {
          // Solo chequear si creemos estar autenticados
          // (evita spam de requests fallidas)
          console.log('[Auth] Tab visible again, checking auth...')
          checkAuth(false)
        }
      }
      document.addEventListener('visibilitychange', visibilityChangeListener)
    }

    // También chequea cuando la ventana recibe foco
    if (typeof window !== 'undefined' && !focusListener) {
      focusListener = () => {
        if (isAuthenticated.value) {
          // Solo chequear si creemos estar autenticados
          console.log('[Auth] Window focused, checking auth...')
          checkAuth(false)
        }
      }
      window.addEventListener('focus', focusListener)
    }
    */
  }

  const cleanupListeners = () => {
    if (visibilityChangeListener) {
      document.removeEventListener('visibilitychange', visibilityChangeListener)
      visibilityChangeListener = null
    }
    if (focusListener) {
      window.removeEventListener('focus', focusListener)
      focusListener = null
    }
  }

  const authStatus = computed(() => {
    // Si estamos offline, mostrar estado offline
    if (isOffline.value) return 'offline'
    if (!authChecked.value) return 'unknown'
    return isAuthenticated.value ? 'authenticated' : 'unauthenticated'
  })

  return {
    isAuthenticated,
    authChecked,
    isCheckingAuth,
    isOffline,
    authStatus,
    userInfo,
    checkAuth,
    triggerAuth,
    fetchUserInfo,
    logout,
    markUnauthenticated,
    setupVisibilityListener,
    cleanupListeners
  }
}
