export interface Webhook {
  id: string;
  restaurantId: string;
  endpointUrl: string;
  events: string[];
  secret: string;
  status: 'active' | 'inactive';
  successRate?: number;
  totalDeliveries?: number;
  createdAt: string;
  updatedAt?: string;
}

export interface WebhookListResponse {
  webhooks: Webhook[];
}

function normalize(row: Record<string, unknown>): Webhook {
  const rawEvents = (row.events ?? []) as string[] | string;
  const events = typeof rawEvents === 'string'
    ? (() => { try { return JSON.parse(rawEvents); } catch { return []; } })()
    : rawEvents;
  return {
    id: row.id as string,
    restaurantId: (row.restaurantId ?? row.restaurant_id) as string,
    endpointUrl: (row.endpointUrl ?? row.endpoint_url) as string,
    events: Array.isArray(events) ? events : [],
    secret: row.secret as string,
    status: row.status as 'active' | 'inactive',
    successRate: (row.successRate ?? row.success_rate) as number | undefined,
    totalDeliveries: (row.totalDeliveries ?? row.total_deliveries) as number | undefined,
    createdAt: (row.createdAt ?? row.created_at) as string,
    updatedAt: (row.updatedAt ?? row.updated_at) as string | undefined,
  };
}

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

export async function listWebhooks(): Promise<WebhookListResponse> {
  const data = await apiFetch<{ webhooks: Record<string, unknown>[] }>('/api/webhooks');
  return { webhooks: data.webhooks.map(normalize) };
}

export async function getWebhook(id: string): Promise<{ webhook: Webhook }> {
  const data = await apiFetch<{ webhook: Record<string, unknown> }>(`/api/webhooks/${id}`);
  return { webhook: normalize(data.webhook) };
}

export async function createWebhook(body: Record<string, unknown>): Promise<{ webhook: Webhook }> {
  const data = await apiFetch<{ webhook: Record<string, unknown> }>('/api/webhooks', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  return { webhook: normalize(data.webhook) };
}

export async function updateWebhook(id: string, body: Record<string, unknown>): Promise<{ webhook: Webhook }> {
  const data = await apiFetch<{ webhook: Record<string, unknown> }>(`/api/webhooks/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  return { webhook: normalize(data.webhook) };
}

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

export interface DeliveryLog {
  id: string;
  webhookId: string;
  restaurantId: string;
  event: string;
  status: 'success' | 'failed' | 'pending';
  responseCode: number | null;
  responseBody: string | null;
  durationMs: number | null;
  errorMessage: string | null;
  triggeredAt: string;
  endpointUrl: string;
}

function normalizeLog(row: Record<string, unknown>): DeliveryLog {
  return {
    id: row.id as string,
    webhookId: (row.webhookId ?? row.webhook_id) as string,
    restaurantId: (row.restaurantId ?? row.restaurant_id) as string,
    event: row.event as string,
    status: row.status as 'success' | 'failed' | 'pending',
    responseCode: (row.responseCode ?? row.response_code) as number | null,
    responseBody: (row.responseBody ?? row.response_body ?? null) as string | null,
    durationMs: (row.durationMs ?? row.duration_ms) as number | null,
    errorMessage: (row.errorMessage ?? row.error_message) as string | null,
    triggeredAt: (row.triggeredAt ?? row.triggered_at) as string,
    endpointUrl: (row.endpointUrl ?? row.endpoint_url) as string,
  };
}

export async function listDeliveryLogs(webhookId?: string): Promise<{ logs: DeliveryLog[] }> {
  const qs = webhookId ? `?webhook_id=${encodeURIComponent(webhookId)}` : '';
  const data = await apiFetch<{ logs: Record<string, unknown>[] }>(`/api/webhooks/delivery-logs${qs}`);
  return { logs: data.logs.map(normalizeLog) };
}
