import type { Resp } from '@/types'

export async function useFetchJson<T = unknown>(url: string, opt?: RequestInit): Promise<Resp<T>> {
  const prefix = import.meta.env.VITE_API_URL ?? ''
  const urlFull = join(prefix, url)

  const headers = new Headers(opt?.headers)
  if (!headers.has('Content-Type')) {
    headers.set('Content-Type', 'application/json')
  }

  const fetchOptions: RequestInit = {
    ...opt,
    headers,
    // Always include cookies so the backend can read the HTTPOnly access_token
    credentials: 'same-origin',
  }

  try {
    const res = await fetch(urlFull, fetchOptions)

    const contentType = res.headers.get('content-type') ?? ''

    if (!contentType.includes('application/json')) {
      throw { message: 'this is not proper json format' } as Resp<any>
    }

    const data = await res.json()

    // Handle 401 — access token expired; try to refresh via the HTTPOnly refresh_token cookie
    if (res.status === 401) {
      const { useAuthStore } = await import('@/stores/auth')
      const authStore = useAuthStore()

      const refreshed = await authStore.refreshAccessToken()

      if (refreshed) {
        // Retry the original request — cookies are updated by the refresh endpoint
        const retryRes = await fetch(urlFull, fetchOptions)

        const retryContentType = retryRes.headers.get('content-type') ?? ''
        if (!retryContentType.includes('application/json')) {
          throw { message: 'this is not proper json format' } as Resp<any>
        }

        const retryData = await retryRes.json()

        if (!retryRes.ok) {
          throw retryData as Resp<any>
        }

        return retryData as Resp<T>
      }

      // Refresh failed — logout and propagate the error
      authStore.logout()
      throw data as Resp<any>
    }

    if (!res.ok) {
      throw data as Resp<any>
    }

    return data as Resp<T>
  } catch (error) {
    throw error as Resp<any>
  }
}

export function join(...parts: string[]): string {
  const path = parts
    .filter(Boolean)
    .join('/')
    .replace(/\/{2,}/g, '/')

  return path.startsWith('/') ? path : `/${path}`
}
