import type { ApiErrorBody } from './types'

export class ApiError extends Error {
  readonly code: string
  readonly requestId: string
  readonly retryable: boolean
  readonly status: number

  constructor(
    message: string,
    code: string,
    requestId: string,
    retryable = false,
    status = 0,
  ) {
    super(message)
    this.name = 'ApiError'
    this.code = code
    this.requestId = requestId
    this.retryable = retryable
    this.status = status
  }
}

export async function apiRequest<T>(path: string, init?: RequestInit): Promise<T> {
  const headers = new Headers(init?.headers)
  if (init?.body && !(init.body instanceof FormData)) headers.set('Content-Type', 'application/json')
  const response = await fetch(path, { ...init, headers })
  if (!response.ok) {
    const body = (await response.json().catch(() => null)) as ApiErrorBody | null
    throw new ApiError(
      body?.error.message ?? `请求失败（${response.status}）`,
      body?.error.code ?? 'HTTP_ERROR',
      body?.error.request_id ?? response.headers.get('X-Request-ID') ?? '',
      body?.error.retryable ?? false,
      response.status,
    )
  }
  if (response.status === 204) return undefined as T
  return (await response.json()) as T
}
