/**
 * Shared HTTP helpers for tool executors.
 * Calls loopback tablet API routes with Bearer + x-voice-internal headers.
 */

export class ToolHttpError extends Error {
  constructor(public status: number, public body: string) {
    super(`tool_http_${status}`)
  }
}

const baseUrl = () => `http://localhost:${process.env.PORT || '3000'}`

export function headers(): Record<string, string> {
  const key = process.env.VOICE_API_KEY || ''
  return {
    Authorization: `Bearer ${key}`,
    'x-voice-internal': key,
    'Content-Type': 'application/json',
  }
}

export async function tabletGet(path: string, params?: Record<string, string>): Promise<any> {
  const url = new URL(`${baseUrl()}${path}`)
  if (params) {
    for (const [k, v] of Object.entries(params)) {
      if (v !== undefined && v !== '') url.searchParams.set(k, v)
    }
  }
  const r = await fetch(url, { headers: headers(), cache: 'no-store' })
  if (!r.ok) throw new ToolHttpError(r.status, await r.text().catch(() => ''))
  return r.json()
}

export async function tabletJson(
  method: 'POST' | 'PUT' | 'DELETE',
  path: string,
  body?: any,
  params?: Record<string, string>,
): Promise<any> {
  const url = new URL(`${baseUrl()}${path}`)
  if (params) {
    for (const [k, v] of Object.entries(params)) {
      if (v !== undefined && v !== '') url.searchParams.set(k, v)
    }
  }
  const r = await fetch(url, {
    method,
    headers: headers(),
    body: body !== undefined ? JSON.stringify(body) : undefined,
  })
  if (!r.ok) throw new ToolHttpError(r.status, await r.text().catch(() => ''))
  return r.json()
}
