import { ENV } from "../config/environment";
import { logger } from "../utils/logger";
import type { ApiError } from "../types/API";

export class ApiClientError extends Error {
  status: number;
  body: ApiError;

  constructor(status: number, body: ApiError) {
    super(body.detail || body.message || `HTTP ${status}`);
    this.status = status;
    this.body = body;
  }
}

async function parseError(response: Response): Promise<ApiClientError> {
  let body: ApiError = {};
  try {
    body = await response.json();
  } catch {
    body = { message: response.statusText };
  }
  return new ApiClientError(response.status, body);
}

export async function apiGet<T>(path: string): Promise<T> {
  const url = `${ENV.API_BASE_URL}${path}`;
  logger.info("GET", url);
  const response = await fetch(url);
  if (!response.ok) throw await parseError(response);
  return response.json() as Promise<T>;
}

export async function apiPost<T>(path: string, body?: unknown): Promise<T> {
  const url = `${ENV.API_BASE_URL}${path}`;
  logger.info("POST", url);
  const response = await fetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: body ? JSON.stringify(body) : undefined,
  });
  if (!response.ok) throw await parseError(response);
  return response.json() as Promise<T>;
}

export async function apiPostFormData<T>(path: string, form: FormData): Promise<T> {
  const url = `${ENV.API_BASE_URL}${path}`;
  logger.info("POST form", url);
  const response = await fetch(url, { method: "POST", body: form });
  if (!response.ok) throw await parseError(response);
  return response.json() as Promise<T>;
}
