const BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:5270'

let authToken = null

export function setAuthToken(token) {
  authToken = token
}

function authHeaders(extra = {}) {
  const headers = { 'Content-Type': 'application/json', ...extra }
  if (authToken) headers['Authorization'] = `Bearer ${authToken}`
  return headers
}

async function request(path, options = {}) {
  const res = await fetch(`${BASE_URL}${path}`, {
    headers: authHeaders(options.headers),
    ...options,
  })
  if (res.status === 401) {
    throw new Error('Session expired — please log in again.')
  }
  const envelope = await res.json()
  if (!res.ok || !envelope.success) {
    const msg = envelope.error?.message ?? `API ${res.status}: ${path}`
    throw new Error(msg)
  }
  return envelope.data
}

/** Returns null when the resource does not exist yet (HTTP 404 or empty optional payload). */
async function requestOptional(path) {
  const res = await fetch(`${BASE_URL}${path}`, {
    headers: authHeaders(),
  })
  if (res.status === 404) return null
  if (res.status === 401) {
    throw new Error('Session expired — please log in again.')
  }
  const envelope = await res.json()
  if (!res.ok || !envelope.success) {
    const msg = envelope.error?.message ?? `API ${res.status}: ${path}`
    throw new Error(msg)
  }
  return envelope.data ?? null
}

export const api = {
  get: (path) => request(path),
  getOptional: (path) => requestOptional(path),
  post: (path, body) => request(path, {
    method: 'POST',
    body: body !== undefined ? JSON.stringify(body) : undefined,
  }),
  put: (path, body) => request(path, {
    method: 'PUT',
    body: body !== undefined ? JSON.stringify(body) : undefined,
  }),
  patch: (path, body) => request(path, {
    method: 'PATCH',
    body: body !== undefined ? JSON.stringify(body) : undefined,
  }),
  delete: async (path) => {
    const res = await fetch(`${BASE_URL}${path}`, {
      method: 'DELETE',
      headers: authHeaders(),
    })
    if (res.status === 401) {
      throw new Error('Session expired — please log in again.')
    }
    if (res.status === 204) return null
    const envelope = await res.json()
    if (!res.ok || !envelope.success) {
      const msg = envelope.error?.message ?? `API ${res.status}: ${path}`
      throw new Error(msg)
    }
    return envelope.data ?? null
  },
}

export { BASE_URL, authHeaders }
