type ApiRequestOptions = {
  method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
  body?: unknown;
  headers?: HeadersInit;
};

type ApiResponse<T = any> = {
  data: T;
  status: number;
  headers: Headers;
};

const API_BASE = "";

async function request<T = any>(path: string, options: ApiRequestOptions = {}): Promise<ApiResponse<T>> {
  const headers: HeadersInit = {
    Accept: "application/json",
    ...options.headers,
  };

  const init: RequestInit = {
    method: options.method ?? "GET",
    credentials: "include",
    headers,
  };

  if (options.body !== undefined) {
    init.body = JSON.stringify(options.body);
    (init.headers as Record<string, string>)["Content-Type"] = "application/json";
  }

  const res = await fetch(`${API_BASE}${path}`, init);
  const raw = await res.text();
  const data = raw ? JSON.parse(raw) : null;

  if (!res.ok) {
    const message = (data && (data.message || data.error)) || `Request failed (${res.status})`;
    throw new Error(message);
  }

  return { data: data as T, status: res.status, headers: res.headers };
}

export const api = {
  get: <T = any>(path: string, headers?: HeadersInit) => request<T>(path, { method: "GET", headers }),
  post: <T = any>(path: string, body?: unknown, headers?: HeadersInit) => request<T>(path, { method: "POST", body, headers }),
  put: <T = any>(path: string, body?: unknown, headers?: HeadersInit) => request<T>(path, { method: "PUT", body, headers }),
  patch: <T = any>(path: string, body?: unknown, headers?: HeadersInit) => request<T>(path, { method: "PATCH", body, headers }),
  delete: <T = any>(path: string, headers?: HeadersInit) => request<T>(path, { method: "DELETE", headers }),
};
