export interface ApiResponse<T = unknown> {
  status: number
  data: T
  ok: boolean
}

export interface ApiClient {
  get<T = unknown>(path: string, params?: Record<string, unknown>): Promise<ApiResponse<T>>
  post<T = unknown>(path: string, body?: unknown): Promise<ApiResponse<T>>
  patch<T = unknown>(path: string, body?: unknown): Promise<ApiResponse<T>>
  del<T = unknown>(path: string): Promise<ApiResponse<T>>
}

function buildQueryString(params?: Record<string, unknown>): string {
  if (!params) return ''
  const sp = new URLSearchParams()
  for (const [k, v] of Object.entries(params)) {
    if (v !== undefined && v !== null && v !== '') sp.set(k, String(v))
  }
  const qs = sp.toString()
  return qs ? `?${qs}` : ''
}

export function createClient(baseUrl: string, token?: string): ApiClient {
  async function request<T>(method: string, path: string, body?: unknown): Promise<ApiResponse<T>> {
    const headers: Record<string, string> = {}
    if (body !== undefined) headers['Content-Type'] = 'application/json'
    if (token) headers['Authorization'] = `Bearer ${token}`

    const res = await fetch(`${baseUrl}${path}`, {
      method,
      headers,
      body: body !== undefined ? JSON.stringify(body) : undefined,
    })

    const data = await res.json() as T
    return { status: res.status, data, ok: res.ok }
  }

  return {
    get: <T>(path: string, params?: Record<string, unknown>) => request<T>('GET', `${path}${buildQueryString(params)}`),
    post: <T>(path: string, body?: unknown) => request<T>('POST', path, body),
    patch: <T>(path: string, body?: unknown) => request<T>('PATCH', path, body),
    del: <T>(path: string) => request<T>('DELETE', path),
  }
}
