import type { ApiResult } from "./types";
import { authState } from "./auth";

const apiBaseUrl = import.meta.env.VITE_API_BASE_URL ?? "";

export function apiGet<T>(path: string): Promise<ApiResult<T>> {
  return apiRequest<T>("GET", path);
}

export function apiPost<T>(path: string, body: unknown): Promise<ApiResult<T>> {
  return apiRequest<T>("POST", path, body);
}

export function apiPut<T>(path: string, body: unknown): Promise<ApiResult<T>> {
  return apiRequest<T>("PUT", path, body);
}

export function apiPatch<T>(path: string, body: unknown): Promise<ApiResult<T>> {
  return apiRequest<T>("PATCH", path, body);
}

export function apiDelete<T>(path: string): Promise<ApiResult<T>> {
  return apiRequest<T>("DELETE", path);
}

async function apiRequest<T>(method: string, path: string, body?: unknown): Promise<ApiResult<T>> {
  try {
    const response = await fetch(`${apiBaseUrl}${path}`, {
      method,
      headers: {
        "Content-Type": "application/json",
        ...(authState.session?.accessToken ? { Authorization: `Bearer ${authState.session.accessToken}` } : {})
      },
      body: body === undefined ? undefined : JSON.stringify(body)
    });

    const text = await response.text();
    const data = text ? parseResponseBody(text) : {};

    if (!response.ok) {
      return { ok: false, message: responseMessage(data, text, response.status) };
    }

    return { ok: true, data: data as T };
  } catch (error) {
    return {
      ok: false,
      message: error instanceof Error ? error.message : "Unbekannter Fehler"
    };
  }
}

function parseResponseBody(text: string): Record<string, unknown> {
  try {
    const parsed = JSON.parse(text);
    return typeof parsed === "object" && parsed !== null ? parsed as Record<string, unknown> : { message: String(parsed) };
  } catch {
    return { message: text };
  }
}

function responseMessage(data: Record<string, unknown>, text: string, status: number): string {
  for (const key of ["message", "detail"]) {
    const value = data[key];
    if (typeof value === "string" && value.trim()) return value;
  }
  return text || `HTTP ${status}`;
}
