/**
 * API Client for Mosaic Stack
 * Handles authenticated requests to the backend API
 */

/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-misused-spread */

const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3001";

export interface ApiError {
  code: string;
  message: string;
  details?: unknown;
}

export interface ApiResponse<T> {
  data: T;
  meta?: {
    total?: number;
    page?: number;
    limit?: number;
  };
}

/**
 * Make an authenticated API request
 */
export async function apiRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
  const url = `${API_BASE_URL}${endpoint}`;

  const response = await fetch(url, {
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...(options.headers ?? {}),
    },
    credentials: "include", // Include cookies for session
  });

  if (!response.ok) {
    const error: ApiError = await response.json().catch(
      (): ApiError => ({
        code: "UNKNOWN_ERROR",
        message: response.statusText || "An unknown error occurred",
      })
    );

    throw new Error(error.message);
  }

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

/**
 * GET request helper
 */
export async function apiGet<T>(endpoint: string): Promise<T> {
  return apiRequest<T>(endpoint, { method: "GET" });
}

/**
 * POST request helper
 */
export async function apiPost<T>(endpoint: string, data?: unknown): Promise<T> {
  const options: RequestInit = {
    method: "POST",
  };

  if (data !== undefined) {
    options.body = JSON.stringify(data);
  }

  return apiRequest<T>(endpoint, options);
}

/**
 * PATCH request helper
 */
export async function apiPatch<T>(endpoint: string, data: unknown): Promise<T> {
  return apiRequest<T>(endpoint, {
    method: "PATCH",
    body: JSON.stringify(data),
  });
}

/**
 * DELETE request helper
 */
export async function apiDelete<T>(endpoint: string): Promise<T> {
  return apiRequest<T>(endpoint, { method: "DELETE" });
}
