const BASE = "";

export interface ApiError {
  error: string;
  details?: string;
}

export async function api<T = unknown>(
  path: string,
  options: RequestInit = {}
): Promise<T> {
  const res = await fetch(`${BASE}${path}`, {
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options.headers,
    },
    credentials: "same-origin",
  });

  if (res.status === 401) {
    window.location.href = `/auth/discord?return_to=${encodeURIComponent(window.location.href)}`;
    throw new Error("Unauthorized");
  }

  if (!res.ok) {
    const body = await res.json().catch(() => ({ error: res.statusText }));
    throw body as ApiError;
  }

  if (res.status === 204 || res.headers.get("content-length") === "0") {
    return undefined as T;
  }

  return res.json() as Promise<T>;
}

export const get = <T = unknown>(path: string) => api<T>(path);

export const post = <T = unknown>(path: string, data?: unknown) =>
  api<T>(path, { method: "POST", body: data ? JSON.stringify(data) : undefined });

export const put = <T = unknown>(path: string, data?: unknown) =>
  api<T>(path, { method: "PUT", body: data ? JSON.stringify(data) : undefined });

export const del = <T = unknown>(path: string) =>
  api<T>(path, { method: "DELETE" });
