import { tokenStorage } from "./storage"
import { rawFetchNoAuth } from "./client"

type RefreshResponse = { access: string }

// Singleton: if a refresh is already in flight, all callers await the same promise.
// Without this, parallel 401s (e.g. Promise.all with 3 calls) would each try to
// refresh simultaneously — only the first succeeds, the others invalidate it.
let _inflightRefresh: Promise<string | null> | null = null

async function _doRefresh(): Promise<string | null> {
  const refresh = tokenStorage.getRefresh()
  if (!refresh) return null

  try {
    const res = await rawFetchNoAuth("/auth/token/refresh/", {
      method: "POST",
      body: JSON.stringify({ refresh }),
    })

    if (!res.ok) return null

    const data = (await res.json()) as RefreshResponse
    tokenStorage.setTokens(data.access, refresh)
    return data.access
  } catch {
    return null
  }
}

export async function refreshAccessToken(): Promise<string | null> {
  if (_inflightRefresh) {
    // Another request already started a refresh — wait for it and reuse
    return _inflightRefresh
  }

  _inflightRefresh = _doRefresh()
  try {
    return await _inflightRefresh
  } finally {
    _inflightRefresh = null
  }
}
