function resolveDefaultBaseUrl(): string {
  if (typeof window !== "undefined") {
    return "/api";
  }
  return "http://localhost:8000";
}

const baseUrl = (import.meta.env.VITE_API_BASE_URL ?? resolveDefaultBaseUrl()).replace(/\/$/, "");

let authToken: string | null = null;

export function setAuthToken(token: string | null) {
  authToken = token;
}

export interface ApiError extends Error {
  status?: number;
  details?: unknown;
}

type ApiRequestInit = Omit<RequestInit, "body"> & {
  body?: unknown;
  skipAuth?: boolean;
};

export async function request<T = unknown>(path: string, options: ApiRequestInit = {}): Promise<T> {
  const url = `${baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
  const { skipAuth, body, headers, ...rest } = options;

  const requestHeaders = new Headers(headers ?? {});
  requestHeaders.set("Accept", "application/json");

  const hasBody = body !== undefined && body !== null;
  const rawBody = body as any;
  const isFormData = hasBody && typeof FormData !== "undefined" && rawBody instanceof FormData;

  if (hasBody && !isFormData) {
    requestHeaders.set("Content-Type", "application/json");
  }

  if (!skipAuth && authToken) {
    requestHeaders.set("Authorization", `Bearer ${authToken}`);
  }

  let requestBody: BodyInit | null | undefined = undefined;
  if (hasBody) {
    requestBody = isFormData ? (rawBody as FormData) : JSON.stringify(rawBody);
  }

  const response = await fetch(url, {
    ...rest,
    headers: requestHeaders,
    body: requestBody
  });

  const contentType = response.headers.get("content-type");
  const isJson = contentType?.includes("application/json");
  const payload = isJson ? await response.json().catch(() => undefined) : await response.text();

  if (!response.ok) {
    const error: ApiError = new Error(
      typeof payload === "string" && payload ? payload : "Request failed"
    );
    error.status = response.status;
    error.details = payload;
    throw error;
  }

  return payload as T;
}

export function clearAuthToken() {
  authToken = null;
}
