// Tiny API client. Token is read once from localStorage and attached to every
// request. WS endpoints use ?token= query (browsers can't set ws headers).

const TOKEN_KEY = 'write.token'

export function getToken(): string {
  return localStorage.getItem(TOKEN_KEY) || ''
}

export function setToken(t: string): void {
  localStorage.setItem(TOKEN_KEY, t)
}

function authHeaders(): Record<string, string> {
  const t = getToken()
  return t ? { Authorization: `token ${t}` } : {}
}

async function req<T>(method: string, path: string, body?: unknown): Promise<T> {
  const headers: Record<string, string> = { ...authHeaders() }
  if (body !== undefined) headers['Content-Type'] = 'application/json'
  const r = await fetch(path, {
    method,
    headers,
    body: body === undefined ? undefined : JSON.stringify(body),
  })
  if (!r.ok) {
    const text = await r.text().catch(() => '')
    throw new Error(`${method} ${path} → ${r.status}: ${text}`)
  }
  if (r.status === 204) return undefined as T
  return r.json() as Promise<T>
}

export interface DocMeta {
  id: number
  title: string
  created_at: string
  updated_at: string
}

export interface DocFull extends DocMeta {
  content: string
}

export interface ChatResponse {
  content: string
  reply: string
  cost_usd?: number
  turns?: number
  duration_ms?: number
}

export const api = {
  listDocs: () => req<DocMeta[]>('GET', '/api/docs'),
  createDoc: (title?: string) => req<DocMeta>('POST', '/api/docs', { title }),
  getDoc: (id: number) => req<DocFull>('GET', `/api/docs/${id}`),
  deleteDoc: (id: number) => req<void>('DELETE', `/api/docs/${id}`),
  saveContent: (id: number, content: string, title?: string) =>
    req<DocMeta>('PUT', `/api/docs/${id}/content`, { content, title }),
  chat: (id: number, text: string) =>
    req<ChatResponse>('POST', `/api/docs/${id}/chat`, { text }),
}

export function asrWsUrl(): string {
  const proto = location.protocol === 'https:' ? 'wss:' : 'ws:'
  const t = getToken()
  return `${proto}//${location.host}/asr?token=${encodeURIComponent(t)}`
}
