import type { PricingBreakdown } from "@/types/order";

/**
 * Frontend-only data contracts for the Signature ticket-purchase wizard —
 * per `flow payment/prompt.txt`. Deliberately separate from `types/order.ts`
 * (the real `Order` model).
 *
 * `holders` is a flat array, but for package ticket types
 * (`TicketType.people_per_ticket === 2`, e.g. "Piknik") it's grouped in
 * order by ticket unit: [unit1-person1, unit1-person2, unit2-person1, ...],
 * length === quantity * peoplePerTicket. `CheckoutWizard.setQuantity` is
 * responsible for keeping the array sized correctly.
 */
export interface HolderData {
  name: string;
  email: string;
  phone: string;
  ktp: string;
  age: string;
}

export const EMPTY_HOLDER: HolderData = { name: "", email: "", phone: "", ktp: "", age: "" };

// `ticket_type_id`/`ticket_phase_id` are always either null (event-wide/
// category-wide) or exactly this wizard's own ticketType.id/ticketPhase.id —
// StepTotalOrder rejects applying a code scoped to a *different*
// category/phase outright, since this wizard only ever buys one phase, so
// there's no partial-eligibility case to represent here (unlike the generic
// multi-phase checkout-form.tsx).
export interface AppliedPromo {
  code: string;
  ticket_type_id: number | null;
  ticket_phase_id: number | null;
  discount_percentage: number;
}

export interface AppliedVoucher {
  code: string;
  ticket_type_id: number | null;
  ticket_phase_id: number | null;
  discount_amount: string;
}

export interface CheckoutState {
  quantity: number;
  holders: HolderData[];
  termsAcceptedAt: string | null;
  promo: AppliedPromo | null;
  voucher: AppliedVoucher | null;
  /** Last fetched POST /checkout/quote result — StepTotalOrder fetches it, StepConfirmation just displays it (never recomputes). */
  quote: PricingBreakdown | null;
}

export function initialCheckoutState(peoplePerTicket: number): CheckoutState {
  return {
    quantity: 1,
    holders: Array.from({ length: peoplePerTicket }, () => EMPTY_HOLDER),
    termsAcceptedAt: null,
    promo: null,
    voucher: null,
    quote: null,
  };
}

export type WizardStep = 1 | 2 | 3 | 4;

export function isHolderValid(holder: HolderData): boolean {
  const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(holder.email);
  const phoneOk = /^\d{8,15}$/.test(holder.phone);
  const ktpOk = /^\d{16}$/.test(holder.ktp);
  const ageOk = /^\d+$/.test(holder.age) && Number(holder.age) >= 0;

  return holder.name.trim().length > 0 && emailOk && phoneOk && ktpOk && ageOk;
}

export function maskKtp(ktp: string): string {
  if (ktp.length < 4) return "•".repeat(ktp.length);
  return "•".repeat(ktp.length - 4) + ktp.slice(-4);
}
