/**
 * Auth composable - replaces @nuxtjs/auth-next
 * Handles login, logout, token refresh, Firebase init, and user state.
 */
import {
  initFirebaseAuth,
  scheduleTokenRefresh,
  setMyPresence,
  cleanupFirebase,
} from '~/services/firebase'

let tokenRefreshTimer: ReturnType<typeof setInterval> | null = null

export function useAuth() {
  const authStore = useAuthStore()
  const chatStore = useChatStore()

  const loading = ref(false)
  const error = ref<string | null>(null)

  async function login(email: string, password: string) {
    loading.value = true
    error.value = null

    try {
      const config = useRuntimeConfig()
      const res = await $fetch<{
        access_token: string
        refresh_token?: string
        me: any
      }>('/auth/login', {
        baseURL: config.public.apiBaseUrl as string,
        method: 'POST',
        body: { email, password },
      })

      // Check if user is admin - redirect to dashboard
      const adminRoles = ['Admin', 'Admin-Customer-Service', 'Admin-Procurement-Operations', 'Admin-Finance']
      if (res.me?.role?.some((r: string) => adminRoles.includes(r))) {
        window.location.href = 'https://dashboard.vyahealthcare.sa'
        return
      }

      authStore.setAuth(res)

      // Initialize Firebase chat after successful login
      if (authStore.token && authStore.user) {
        initFirebaseAuth(authStore.token)
          .then(() => {
            scheduleTokenRefresh(authStore.token!)
            setMyPresence(authStore.user!.id, true)
            chatStore.setFirebaseConnected(true)
          })
          .catch((e) => console.error('Firebase init after login failed:', e))
      }

      // Start automatic token refresh scheduling
      startTokenRefreshSchedule()

      await navigateTo('/')
    } catch (e: any) {
      error.value = e?.data?.error || e?.data?.message || 'Login failed'
      throw e
    } finally {
      loading.value = false
    }
  }

  async function logout() {
    // Cleanup Firebase
    if (authStore.user) {
      setMyPresence(authStore.user.id, false).catch(() => {})
    }
    cleanupFirebase()
    chatStore.clearChat()
    chatStore.setFirebaseConnected(false)

    // Stop token refresh
    stopTokenRefreshSchedule()

    authStore.logout()
    await navigateTo('/auth/login')
  }

  function initAuth() {
    authStore.restoreFromCookies()

    // If restored from cookies, start token refresh schedule
    if (authStore.loggedIn && authStore.token) {
      startTokenRefreshSchedule()
    }
  }

  /**
   * Schedules automatic token refresh.
   * Tries to decode JWT to calculate optimal refresh time (75% of remaining TTL).
   * Falls back to refreshing every 4 minutes (token maxAge is 300s = 5min).
   */
  function startTokenRefreshSchedule() {
    stopTokenRefreshSchedule()

    if (!authStore.token || !authStore.refreshToken) return

    let refreshInterval = 4 * 60 * 1000 // Default: 4 minutes (token expires at 5 min)

    // Try to decode JWT and calculate optimal refresh time
    try {
      const payload = decodeJwtPayload(authStore.token)
      if (payload?.exp) {
        const remaining = (payload.exp * 1000) - Date.now()
        if (remaining > 10000) {
          refreshInterval = remaining * 0.75 // Refresh at 75% of remaining time
        } else if (remaining > 0) {
          refreshInterval = 100 // Token expiring very soon, refresh immediately
        } else {
          // Token already expired, refresh now
          authStore.refreshTokens()
          return
        }
      }
    } catch {
      // JWT decode failed, use default interval
    }

    tokenRefreshTimer = setInterval(async () => {
      try {
        await authStore.refreshTokens()
      } catch {
        // Refresh failed, will be caught by 401 handler
      }
    }, refreshInterval)
  }

  function stopTokenRefreshSchedule() {
    if (tokenRefreshTimer) {
      clearInterval(tokenRefreshTimer)
      tokenRefreshTimer = null
    }
  }

  return {
    login,
    logout,
    initAuth,
    loading,
    error,
    user: computed(() => authStore.user),
    loggedIn: computed(() => authStore.loggedIn),
    token: computed(() => authStore.token),
  }
}

/**
 * Decode JWT payload without verification (client-side only).
 */
function decodeJwtPayload(token: string): { exp?: number; [key: string]: unknown } | null {
  try {
    const parts = token.split('.')
    if (parts.length !== 3) return null

    let payload = parts[1]
    payload = payload.replace(/-/g, '+').replace(/_/g, '/')

    // Pad with '=' to make valid base64
    while (payload.length % 4) {
      payload += '='
    }

    const decoded = atob(payload)
    return JSON.parse(decoded)
  } catch {
    return null
  }
}
