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 TelephoneSettings {
  id: string;
  restaurant_id: string;
  twilio_connected: boolean;
  twilio_account_sid_hint: string | null;
}

export interface PhoneNumber {
  id: string;
  restaurant_id: string;
  branch_id: string | null;
  number: string;
  display_name: string | null;
  type: string;
  assigned_agent_id: string | null;
  assigned_agent_name: string | null;
  is_active: boolean;
  call_recording: boolean;
  call_transcription: boolean;
  greeting_override: string | null;
  fallback_number: string | null;
  twilio_number_sid: string | null;
}

export interface SipLine extends PhoneNumber {
  sip_config: {
    sip_server?: string;
    sip_username?: string;
    sip_password?: string;
    outbound_proxy?: string;
    registration_status?: string;
  };
}

export async function getTwilioSettings(): Promise<{ settings: TelephoneSettings; numbers: PhoneNumber[] }> {
  return apiFetch('/api/telephone/twilio');
}

export async function connectTwilio(account_sid: string, auth_token: string): Promise<{ connected: boolean; error?: string }> {
  return apiFetch('/api/telephone/twilio', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ account_sid, auth_token }),
  });
}

export async function disconnectTwilio(): Promise<{ success: boolean }> {
  return apiFetch('/api/telephone/twilio', { method: 'DELETE' });
}

export async function listSipLines(): Promise<{ lines: SipLine[] }> {
  return apiFetch('/api/telephone/sip');
}

export async function createSipLine(data: {
  display_name: string;
  sip_server: string;
  sip_username: string;
  sip_password: string;
  outbound_proxy?: string;
  assigned_agent_id?: string;
}): Promise<{ line: SipLine }> {
  return apiFetch('/api/telephone/sip', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  });
}

export async function updateSipLine(id: string, data: Record<string, unknown>): Promise<{ line: SipLine }> {
  return apiFetch(`/api/telephone/sip/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  });
}

export async function deleteSipLine(id: string): Promise<{ success: boolean }> {
  return apiFetch(`/api/telephone/sip/${id}`, { method: 'DELETE' });
}

export async function assignAgent(numberId: string, agentId: string | null): Promise<{ success: boolean }> {
  return apiFetch('/api/telephone/twilio/assign', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ number_id: numberId, agent_id: agentId }),
  });
}

export async function toggleNumberActive(numberId: string, active: boolean): Promise<{ success: boolean }> {
  return apiFetch('/api/telephone/twilio/toggle', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ number_id: numberId, is_active: active }),
  });
}

export interface TwilioRemoteNumber {
  sid: string;
  phone_number: string;
  friendly_name: string;
  capabilities: { voice: boolean; sms: boolean };
}

export async function fetchTwilioNumbers(): Promise<{ numbers: TwilioRemoteNumber[] }> {
  return apiFetch('/api/telephone/twilio/numbers');
}

export async function updateNumberSettings(numberId: string, data: {
  call_recording?: boolean;
  call_transcription?: boolean;
  greeting_override?: string | null;
  fallback_number?: string | null;
  branch_id?: string | null;
}): Promise<{ success: boolean; numbers: PhoneNumber[] }> {
  return apiFetch('/api/telephone/twilio/settings', {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ number_id: numberId, ...data }),
  });
}

export async function makeOutboundCall(to: string, fromNumberId: string): Promise<{ success: boolean; callSid?: string; sessionId?: string }> {
  return apiFetch('/api/telephone/calls/outbound', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ to, from_number_id: fromNumberId }),
  });
}

export async function transferCallApi(sessionId: string, targetNumber: string): Promise<{ success: boolean }> {
  return apiFetch(`/api/telephone/calls/${sessionId}/transfer`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ target_number: targetNumber }),
  });
}

export async function createConferenceApi(sessionId: string, staffNumber?: string): Promise<{ success: boolean; conferenceName?: string; staffCallSid?: string; staffNumberDialed?: string; staffJoinStatus?: string }> {
  return apiFetch(`/api/telephone/calls/${sessionId}/conference`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(staffNumber ? { staff_number: staffNumber } : {}),
  });
}

export interface AvailableTwilioNumber {
  phone_number: string;
  friendly_name: string;
  locality: string;
  region: string;
  capabilities: Record<string, boolean>;
}

export async function searchTwilioNumbers(country: string, params?: { areaCode?: string; type?: string; limit?: number }): Promise<{ numbers: AvailableTwilioNumber[] }> {
  const qs = new URLSearchParams({ country });
  if (params?.areaCode) qs.set('areaCode', params.areaCode);
  if (params?.type) qs.set('type', params.type);
  if (params?.limit) qs.set('limit', String(params.limit));
  return apiFetch(`/api/telephone/twilio/available-numbers?${qs.toString()}`);
}

export async function purchaseTwilioNumber(phoneNumber: string): Promise<{ success: boolean; sid?: string; phone_number?: string; friendly_name?: string }> {
  return apiFetch('/api/telephone/twilio/purchase', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ phone_number: phoneNumber }),
  });
}
