import { useAuthStore } from '@/stores/auth'
import router from '@/router'

const BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api/v1'

export function getToken(): string | null {
  try {
    const authStore = useAuthStore()
    // In Pinia setup stores, refs are auto-unwrapped on store access
    // But be defensive: handle both unwrapped string and raw ref
    const token = authStore.token
    if (!token) return null
    // If token is a ref (rare case), access .value
    return (token as unknown as { value?: string }).value ?? token
  } catch {
    return null
  }
}

export function useApi() {
  async function refreshAccessToken(): Promise<string | null> {
    try {
      const response = await fetch(`${BASE_URL}/auth/refresh`, {
        method: 'POST',
        credentials: 'include'  // Include cookies for refresh token
      })
      if (response.ok) {
        const data = await response.json()
        const authStore = useAuthStore()
        authStore.token = data.access_token
        localStorage.setItem('access_token', data.access_token)
        return data.access_token
      }
    } catch {
      // Refresh failed
    }
    return null
  }

  async function request<T>(method: string, endpoint: string, body?: unknown, retryCount = 0): Promise<T> {
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
    }

    const token = getToken()
    console.log(`[useApi] ${method} ${endpoint} - token: ${token ? 'present' : 'null'}`)

    // Only add Authorization header for non-auth endpoints
    // NOTE: /auth/me DOES need the token to identify the user
    const noAuthEndpoints = ['/auth/login', '/auth/register', '/auth/logout', '/auth/refresh']
    if (token && !noAuthEndpoints.includes(endpoint)) {
      headers['Authorization'] = `Bearer ${token}`
      console.log(`[useApi] Added Authorization header: Bearer ${token.substring(0, 10)}...`)
    } else {
      console.log(`[useApi] NO Authorization header - token=${token ? 'present' : 'null'}, endpoint=${endpoint}`)
    }

    const response = await fetch(`${BASE_URL}${endpoint}`, {
      method,
      headers,
      body: body ? JSON.stringify(body) : undefined,
      credentials: 'include'
    })

    if (response.status === 401) {
      // Try to refresh token once
      if (retryCount === 0 && !endpoint.includes('/auth/')) {
        const newToken = await refreshAccessToken()
        if (newToken) {
          // Retry original request with new token
          headers['Authorization'] = `Bearer ${newToken}`
          const retryResponse = await fetch(`${BASE_URL}${endpoint}`, {
            method,
            headers,
            credentials: 'include',
            body: body ? JSON.stringify(body) : undefined
          })
          if (retryResponse.ok) {
            if (retryResponse.status === 204) {
              return {} as T
            }
            return retryResponse.json()
          }
        }
      }
      const authStore = useAuthStore()
      authStore.logout()
      router.push('/login')
      throw new Error('Unauthorized')
    }

    if (!response.ok) {
      const error = await response.json().catch(() => ({ detail: 'Request failed' }))
      throw new Error(error.detail || `HTTP ${response.status}`)
    }

    if (response.status === 204) {
      return {} as T
    }

    return response.json()
  }

  return {
    get: <T>(endpoint: string) => request<T>('GET', endpoint),
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    post: <T>(endpoint: string, body?: any) => request<T>('POST', endpoint, body),
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    put: <T>(endpoint: string, body?: any) => request<T>('PUT', endpoint, body),
    delete: <T>(endpoint: string) => request<T>('DELETE', endpoint)
  }
}
