export interface OrderItem {
  name: string;
  quantity: number;
  price: number;
  notes?: string;
  note?: string;
  modifiers?: string[];
}

export interface Order {
  id: string;
  restaurantId: string;
  branchId?: string;
  customerId?: string;
  customerName: string;
  customerPhone?: string;
  channel: string;
  status: string;
  items: OrderItem[];
  subtotal?: number;
  tax?: number;
  total: number;
  aiConfidence?: number | null;
  orderNumber?: number;
  deliveryType?: string;
  tableNumber?: string;
  deliveryAddress?: string;
  specialInstructions?: string;
  transcriptSummary?: string;
  agentId?: string;
  conversationId?: string;
  isModified?: boolean;
  placedAt: string;
  modificationNote?: string;
  couponId?: string | null;
  couponCode?: string | null;
  discountAmount?: number;
  giftCardApplied?: number;
  giftCardRemainingBalance?: number | null;
  loyaltyDiscount?: number;
  loyaltyPointsRedeemed?: number;
  loyaltyPointsEarned?: number;
  createdAt: string;
  updatedAt: string;
}

export interface OrderStats {
  totalOrders: number;
  pendingOrders: number;
  completedOrders: number;
  cancelledOrders: number;
  totalRevenue: number;
}

export interface OrderListResponse {
  orders: Order[];
  total: number;
  page: number;
  limit: number;
  pages: number;
}

function normalizeOrderItem(raw: Record<string, unknown>): OrderItem {
  const note = raw.note != null ? String(raw.note) : undefined;
  const notes = raw.notes != null
    ? String(raw.notes)
    : note ?? (Array.isArray(raw.modifiers) ? raw.modifiers.join(', ') : undefined);
  return {
    name: String(raw.name ?? ''),
    quantity: Number(raw.quantity ?? raw.qty ?? 1),
    price: Number(raw.price ?? 0),
    notes,
    note,
    modifiers: Array.isArray(raw.modifiers) ? raw.modifiers.map(String) : undefined,
  };
}

export function normalizeOrder(raw: Record<string, unknown>): Order {
  const rawItems = Array.isArray(raw.items) ? raw.items : [];
  return {
    id: String(raw.id ?? ''),
    restaurantId: String(raw.restaurant_id ?? raw.restaurantId ?? ''),
    branchId: raw.branch_id != null ? String(raw.branch_id) : (raw.branchId != null ? String(raw.branchId) : undefined),
    customerId: raw.customer_id != null ? String(raw.customer_id) : (raw.customerId != null ? String(raw.customerId) : undefined),
    customerName: String(raw.customer_name ?? raw.customerName ?? 'Unknown'),
    customerPhone: raw.customer_phone != null ? String(raw.customer_phone) : (raw.customerPhone != null ? String(raw.customerPhone) : undefined),
    channel: String(raw.channel ?? 'chat'),
    status: String(raw.status ?? 'pending'),
    items: rawItems.map((it: Record<string, unknown>) => normalizeOrderItem(it)),
    subtotal: raw.subtotal != null ? Number(raw.subtotal) : undefined,
    tax: raw.tax != null ? Number(raw.tax) : undefined,
    total: Number(raw.total ?? 0),
    aiConfidence: raw.ai_confidence != null ? Number(raw.ai_confidence) : (raw.aiConfidence != null ? Number(raw.aiConfidence) : null),
    orderNumber: raw.order_number != null ? Number(raw.order_number) : (raw.orderNumber != null ? Number(raw.orderNumber) : undefined),
    deliveryType: raw.delivery_type != null ? String(raw.delivery_type) : (raw.deliveryType != null ? String(raw.deliveryType) : undefined),
    tableNumber: raw.table_number != null ? String(raw.table_number) : (raw.tableNumber != null ? String(raw.tableNumber) : undefined),
    deliveryAddress: raw.delivery_address != null ? String(raw.delivery_address) : (raw.deliveryAddress != null ? String(raw.deliveryAddress) : undefined),
    specialInstructions: raw.special_instructions != null ? String(raw.special_instructions) : (raw.specialInstructions != null ? String(raw.specialInstructions) : undefined),
    transcriptSummary: raw.transcript_summary != null ? String(raw.transcript_summary) : (raw.transcriptSummary != null ? String(raw.transcriptSummary) : undefined),
    agentId: raw.agent_id != null ? String(raw.agent_id) : (raw.agentId != null ? String(raw.agentId) : undefined),
    conversationId: raw.conversation_id != null ? String(raw.conversation_id) : (raw.conversationId != null ? String(raw.conversationId) : undefined),
    isModified: Boolean(raw.is_modified ?? raw.isModified ?? false),
    placedAt: String(raw.placed_at ?? raw.placedAt ?? raw.created_at ?? raw.createdAt ?? ''),
    modificationNote: raw.modification_note != null ? String(raw.modification_note) : (raw.modificationNote != null ? String(raw.modificationNote) : undefined),
    couponId: raw.coupon_id != null ? String(raw.coupon_id) : (raw.couponId != null ? String(raw.couponId) : null),
    couponCode: raw.coupon_code != null ? String(raw.coupon_code) : (raw.couponCode != null ? String(raw.couponCode) : null),
    discountAmount: raw.discount_amount != null ? Number(raw.discount_amount) : (raw.discountAmount != null ? Number(raw.discountAmount) : 0),
    giftCardApplied: raw.gift_card_applied != null ? Number(raw.gift_card_applied) : (raw.giftCardApplied != null ? Number(raw.giftCardApplied) : 0),
    giftCardRemainingBalance: raw.gift_card_remaining_balance != null ? Number(raw.gift_card_remaining_balance) : (raw.giftCardRemainingBalance != null ? Number(raw.giftCardRemainingBalance) : null),
    loyaltyDiscount: raw.loyalty_discount != null ? Number(raw.loyalty_discount) : (raw.loyaltyDiscount != null ? Number(raw.loyaltyDiscount) : 0),
    loyaltyPointsRedeemed: raw.loyalty_points_redeemed != null ? Number(raw.loyalty_points_redeemed) : (raw.loyaltyPointsRedeemed != null ? Number(raw.loyaltyPointsRedeemed) : 0),
    loyaltyPointsEarned: raw.loyalty_points_earned != null ? Number(raw.loyalty_points_earned) : (raw.loyaltyPointsEarned != null ? Number(raw.loyaltyPointsEarned) : 0),
    createdAt: String(raw.created_at ?? raw.createdAt ?? ''),
    updatedAt: String(raw.updated_at ?? raw.updatedAt ?? ''),
  };
}

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 listOrders(params: Record<string, string> = {}): Promise<OrderListResponse> {
  const qs = new URLSearchParams(params).toString();
  const raw = await apiFetch<{ orders: Record<string, unknown>[]; total: number; page: number; limit: number; pages: number }>(`/api/orders${qs ? '?' + qs : ''}`);
  return {
    orders: (raw.orders ?? []).map(normalizeOrder),
    total: raw.total,
    page: raw.page,
    limit: raw.limit,
    pages: raw.pages,
  };
}

export async function getOrderStats(): Promise<{ stats: OrderStats }> {
  return apiFetch<{ stats: OrderStats }>('/api/orders?stats=true');
}

export async function getOrder(id: string): Promise<{ order: Order }> {
  const raw = await apiFetch<{ order: Record<string, unknown> }>(`/api/orders/${id}`);
  return { order: normalizeOrder(raw.order) };
}

export async function createOrder(body: Record<string, unknown>): Promise<{ order: Order }> {
  const raw = await apiFetch<{ order: Record<string, unknown> }>('/api/orders', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  return { order: normalizeOrder(raw.order) };
}

export async function updateOrder(id: string, body: Record<string, unknown>): Promise<{ order: Order }> {
  const raw = await apiFetch<{ order: Record<string, unknown> }>(`/api/orders/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  return { order: normalizeOrder(raw.order) };
}

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