async function apiFetch(url: string, options?: RequestInit) {
  const res = await fetch(url, { credentials: 'include', ...options });
  const json = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(json.error || `Request failed: ${res.status}`);
  return json;
}

export interface AiAgent {
  id: string;
  restaurant_id: string;
  branch_id: string | null;
  name: string;
  description: string | null;
  role: string;
  channels: string[];
  llm_model_id: string | null;
  voice_model_id: string | null;
  voice_language_code: string | null;
  realtime_model: string | null;
  system_prompt: string | null;
  greeting_script: string | null;
  closing_script: string | null;
  fallback_rules: { trigger: string; action: string; priority?: string }[];
  capabilities: Record<string, unknown>;
  is_active: boolean;
  is_default: boolean;
  vad_threshold: number | null;
  vad_prefix_padding_ms: number | null;
  vad_silence_duration_ms: number | null;
  menu_category_ids: string[] | null;
  knowledge_base_ids: string[] | null;
  created_at: string;
  updated_at: string;
  llm_model_name?: string;
  llm_provider_name?: string;
  voice_model_name?: string;
  voice_provider_name?: string;
}

export interface LlmProvider {
  id: string;
  name: string;
  display_name: string;
  api_base_url: string;
  is_active: boolean;
  display_order: number;
  models: LlmModel[];
}

export interface LlmModel {
  id: string;
  provider_id: string;
  model_id: string;
  display_name: string;
  context_length: number;
  supports_functions: boolean;
  is_active: boolean;
  display_order: number;
}

export interface VoiceProvider {
  id: string;
  name: string;
  display_name: string;
  api_base_url: string;
  is_active: boolean;
  display_order: number;
  models: VoiceModel[];
}

export interface VoiceModel {
  id: string;
  voice_provider_id: string;
  voice_id: string;
  display_name: string;
  language_code: string;
  gender: string;
  is_active: boolean;
  display_order: number;
}

export interface ProvidersResponse {
  providers: {
    llm: LlmProvider[];
    voice: VoiceProvider[];
  };
}

export async function listAgents(params?: { scope?: 'restaurant' }): Promise<{ agents: AiAgent[] }> {
  const qs = params?.scope ? `?scope=${params.scope}` : '';
  return apiFetch(`/api/ai-agents${qs}`);
}

export async function getAgent(id: string): Promise<{ agent: AiAgent }> {
  return apiFetch(`/api/ai-agents/${id}`);
}

export async function createAgent(body: Partial<AiAgent>): Promise<{ agent: AiAgent }> {
  return apiFetch('/api/ai-agents', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
}

export async function updateAgent(id: string, body: Partial<AiAgent>): Promise<{ agent: AiAgent }> {
  return apiFetch(`/api/ai-agents/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
}

export async function deleteAgent(id: string): Promise<{ success: boolean }> {
  return apiFetch(`/api/ai-agents/${id}`, { method: 'DELETE' });
}

export async function getProviders(): Promise<ProvidersResponse> {
  return apiFetch('/api/ai-agents/providers');
}

export async function syncOpenRouterModels(): Promise<{
  success: boolean;
  fetched: number;
  upserted: number;
  skipped: number;
  error?: string;
}> {
  return apiFetch('/api/ai-agents/providers/sync', { method: 'POST' });
}

export async function previewVoice(voiceModelId: string, text?: string, languageCode?: string): Promise<{ audio: ArrayBuffer; contentType: string }> {
  const res = await fetch('/api/ai-agents/voice-preview', {
    method: 'POST',
    credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ voiceModelId, text, languageCode }),
  });
  if (!res.ok) {
    const json = await res.json().catch(() => ({})) as { error?: string };
    throw new Error(json.error || `Preview failed: ${res.status}`);
  }
  const contentType = res.headers.get('content-type') || 'audio/mpeg';
  const audio = await res.arrayBuffer();
  return { audio, contentType };
}
