/**
 * stores/auth.ts
 *
 * Pinia auth store — JWT token management + admin profile.
 * Token persisted to localStorage; cleared on logout / 401.
 *
 * Backend login flow:
 *   200 → success, returns { access_token, admin }
 *   202 → TOTP required, returns { message }
 *   429 → account locked
 */
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { ApiError, TotpRequiredError, api, http } from '@/api'

export { TotpRequiredError }

export const useAuthStore = defineStore('auth', () => {
  // ── State ──
  const token = ref<string | null>(localStorage.getItem('nexus_token'))
  const admin = ref<AdminProfile | null>(null)

  // ── Getters ──
  const isLoggedIn = computed(() => !!token.value)

  // ── Actions ──
  async function login(username: string, password: string, totp_code?: string) {
    const res = await api<any>('/auth/login', {
      method: 'POST',
      body: JSON.stringify({ username, password, totp_code }),
    })

    // 200 success — store token
    if (res.access_token) {
      token.value = res.access_token
      localStorage.setItem('nexus_token', res.access_token)

      // Store admin from response if available
      if (res.admin) {
        admin.value = res.admin
      } else {
        await fetchProfile()
      }
      return
    }

    // Should not reach here for 200, but just in case
    await fetchProfile()
  }

  async function fetchProfile() {
    if (!token.value) return
    try {
      admin.value = await http.get<AdminProfile>('/auth/me')
    } catch (e: any) {
      // Only force logout on 401 (invalid token), not on network errors
      if (e instanceof ApiError && e.status === 401) {
        forceLogout()
      }
      // Network errors / no backend → keep token, admin stays null
    }
  }

  function logout() {
    token.value = null
    admin.value = null
    localStorage.removeItem('nexus_token')
    // Best-effort server-side logout
    http.post('/auth/logout').catch(() => {})
  }

  function forceLogout() {
    token.value = null
    admin.value = null
    localStorage.removeItem('nexus_token')
  }

  // Init: load profile if token exists
  if (token.value) {
    fetchProfile()
  }

  return { token, admin, isLoggedIn, login, fetchProfile, logout, forceLogout }
})

interface AdminProfile {
  id: number
  username: string
  totp_enabled: boolean
  created_at: string
}
