/**
 * Shared API client targeting Query API, Symbol Registry, and Risk Engine.
 * Base URLs are configurable via env vars (VITE_*).
 */

const QUERY_API_BASE = import.meta.env.VITE_QUERY_API_URL || '';
const SYMBOL_REGISTRY_BASE = import.meta.env.VITE_SYMBOL_REGISTRY_URL || '/registry';
const RISK_ENGINE_BASE = import.meta.env.VITE_RISK_ENGINE_URL || '/risk';
const TRADING_ENGINE_BASE = import.meta.env.VITE_TRADING_ENGINE_URL || '/trading';

export type ApiBase = 'query' | 'registry' | 'risk' | 'trading';

function baseUrl(api: ApiBase): string {
  switch (api) {
    case 'query':
      return QUERY_API_BASE;
    case 'registry':
      return SYMBOL_REGISTRY_BASE;
    case 'risk':
      return RISK_ENGINE_BASE;
    case 'trading':
      return TRADING_ENGINE_BASE;
  }
}

export class ApiError extends Error {
  status: number;
  body: unknown;

  constructor(status: number, body: unknown) {
    super(`API error ${status}`);
    this.name = 'ApiError';
    this.status = status;
    this.body = body;
  }
}

export async function apiFetch<T>(
  api: ApiBase,
  path: string,
  init?: RequestInit,
): Promise<T> {
  const url = `${baseUrl(api)}${path}`;
  const res = await fetch(url, {
    ...init,
    headers: {
      'Content-Type': 'application/json',
      ...init?.headers,
    },
  });
  if (!res.ok) {
    const body = await res.json().catch(() => null);
    throw new ApiError(res.status, body);
  }
  return res.json() as Promise<T>;
}

/** Convenience GET */
export function apiGet<T>(api: ApiBase, path: string): Promise<T> {
  return apiFetch<T>(api, path);
}

/** Convenience POST */
export function apiPost<T>(api: ApiBase, path: string, body: unknown): Promise<T> {
  return apiFetch<T>(api, path, {
    method: 'POST',
    body: JSON.stringify(body),
  });
}

/** Convenience PUT */
export function apiPut<T>(api: ApiBase, path: string, body: unknown): Promise<T> {
  return apiFetch<T>(api, path, {
    method: 'PUT',
    body: JSON.stringify(body),
  });
}

/** Convenience DELETE */
export function apiDelete<T>(api: ApiBase, path: string): Promise<T> {
  return apiFetch<T>(api, path, { method: 'DELETE' });
}
