"use client";

export const dynamic = "force-dynamic";
export const fetchCache = "force-no-store";

import { useRouter } from "next/navigation";
import { useBookingStore } from "@/lib/booking-store";
import { usePaymentStore } from "@/lib/payment-store";
import { useQuery } from "@tanstack/react-query";
import { apiClient } from "@/lib/api-client";
import { useEffect, useRef, useState } from "react";
import { CheckCircle, Clock, Copy, Train, FileText } from "lucide-react";
import { format } from "date-fns";
import { isChild, isFirstChild } from "@/utils/fare-utils";
import { toZonedDate } from "@/utils/format";

type BookingWithTicket = {
  id: string;
  pnr?: string | null;
  status?: string;
  totalMinor?: number;
  createdAt?: string;
  paymentMethod?: string;
  // The actual settled amount/currency for this booking's payment — authoritative over any
  // client-side session state, since it reflects what was really charged server-side.
  payment?: {
    method?: string;
    status?: string;
    amountMinor?: number;
    currency?: string;
  };
  // One ticket per passenger — match by passengerName, not array position (see
  // bookings.service.ts's getByRef).
  tickets?: Array<{
    passengerName?: string;
    barcodePayload?: string;
    qrPayload?: string;
  }>;
};

export default function ConfirmationPage() {
  const router = useRouter();
  const {
    bookingId,
    pnr,
    selectedSchedule,
    outboundSchedule,
    inboundSchedule,
    searchCriteria,
    passengers,
    clearBooking,
    packageName,
    packageId,
    reviewedTotalMinor,
    reviewedPassengerFares,
  } = useBookingStore();
  // The currency/amount actually confirmed for the payment option the user selected —
  // null when no payment step ran (e.g. a fully-discounted, zero-amount booking).
  const { selectedCurrency: paidCurrency, paidAmountMinor } = usePaymentStore();
  const isRoundTrip = searchCriteria?.tripType === "ROUND_TRIP";
  const [copied, setCopied] = useState(false);
  const [isGeneratingVoucher, setIsGeneratingVoucher] = useState(false);

  // Grace period after landing on this page: keep showing the generic "processing"
  // spinner instead of the "payment pending" screen, and poll the payment intent
  // frequently — booking.status and paymentIntent.status flip to CONFIRMED/SUCCEEDED
  // together (see finalizePaymentSuccess in payments.service.ts), so a payment that
  // already succeeded at the provider often just needs a few more seconds for its
  // webhook to reach us. Once the grace period elapses, fall back to the normal
  // pending screen with slower background polling.
  const CONFIRMATION_GRACE_PERIOD_MS = 10_000;
  const FAST_POLL_INTERVAL_MS = 2_500;
  const SLOW_POLL_INTERVAL_MS = 10_000;
  const MAX_TICKET_POLL_ATTEMPTS = 12; // 12 × 2.5s = 30s max wait for tickets
  const mountTimeRef = useRef(Date.now());
  const ticketPollAttemptsRef = useRef(0);
  const [withinGracePeriod, setWithinGracePeriod] = useState(true);

  useEffect(() => {
    const timer = setTimeout(
      () => setWithinGracePeriod(false),
      CONFIRMATION_GRACE_PERIOD_MS,
    );
    return () => clearTimeout(timer);
  }, []);

  // Warms the code-split voucher module ahead of the click so the handler's own
  // `await import(...)` resolves near-instantly — on iOS Safari, a file save triggered
  // too long after the originating click's synchronous execution window is silently
  // blocked, and awaiting a cold dynamic import is enough to fall outside that window.
  useEffect(() => {
    import("@/lib/generate-voucher");
  }, []);

  const {
    data: _booking,
    refetch: refetchBooking,
    isLoading: isBookingLoading,
    isError: isBookingError,
  } = useQuery<BookingWithTicket>({
    queryKey: ["booking", bookingId],
    // Let a real fetch failure surface as a real error (React Query's global retry:1
    // default then retries once automatically) instead of silently returning a
    // fabricated "PENDING_PAYMENT" object — that used to mask genuine failures (a
    // transient blip right after a cross-domain redirect from the payment gateway is
    // common) as normal pending state forever, since a caught error that returns data
    // looks like a success to React Query and never gets retried.
    queryFn: (): Promise<BookingWithTicket> => apiClient.get(`/bookings/${bookingId}`),
    staleTime: 0,
    enabled: !!bookingId && typeof window !== 'undefined',
    // Keep polling after CONFIRMED until tickets are issued — ticket generation runs
    // async after the booking transaction commits (see finalizePaymentSuccess in
    // payments.service.ts), so the first CONFIRMED fetch often returns an empty
    // tickets array. Free children have no ticket, so compare against adult count
    // (at minimum 1 ticket must exist) rather than total passenger count.
    refetchInterval: (query) => {
      const data = query.state.data;
      if (!data || data.status !== "CONFIRMED") return false;
      const adultCount = searchCriteria?.adultCount ?? passengers.filter((p) => !isChild(p)).length;
      const expectedTickets = Math.max(1, adultCount);
      if ((data.tickets?.length ?? 0) >= expectedTickets) {
        ticketPollAttemptsRef.current = 0;
        return false;
      }
      if (ticketPollAttemptsRef.current >= MAX_TICKET_POLL_ATTEMPTS) return false;
      ticketPollAttemptsRef.current += 1;
      return FAST_POLL_INTERVAL_MS;
    },
  });

  // Poll the payment intent while the booking is PENDING_PAYMENT — fast during the
  // grace period (catches a webhook that's just a few seconds behind), then slower
  // in the background afterward. The backend auto-confirms (and generates tickets)
  // when the payment-api reports SUCCEEDED, so detecting that here means the
  // booking is now CONFIRMED — refetch to update the UI without requiring the user
  // to refresh.
  const { data: intentStatus } = useQuery<any>({
    queryKey: ["payment-intent-status", bookingId],
    queryFn: () => apiClient.get(`/payments/intents/${bookingId}`),
    enabled: _booking?.status === "PENDING_PAYMENT" && !!bookingId && typeof window !== 'undefined',
    staleTime: 0,
    refetchInterval: () =>
      Date.now() - mountTimeRef.current < CONFIRMATION_GRACE_PERIOD_MS
        ? FAST_POLL_INTERVAL_MS
        : SLOW_POLL_INTERVAL_MS,
  });

  useEffect(() => {
    if (intentStatus?.status === "SUCCEEDED") {
      refetchBooking();
    }
  }, [intentStatus?.status, refetchBooking]);

  // Only trust an actually-confirmed booking to show ticket numbers / a "CONFIRMED" badge —
  // a gateway redirect back here does not mean payment succeeded (see payment return pages).
  // Ticket generation itself is never triggered from this page — the payment webhook
  // generates it server-side (for every payment method, wallet included); this page only
  // ever fetches and displays whatever the booking query above already returns.
  const isConfirmed = _booking?.status === "CONFIRMED";

  const copyPNR = () => {
    if (pnr) {
      navigator.clipboard.writeText(pnr);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  };

  const handleDownloadVoucher = async () => {
    if (!pnr || !bookingId) {
      alert("Booking data not available. Please try again.");
      return;
    }
    if (!passengers.length) {
      alert("No passenger data found.");
      return;
    }

    setIsGeneratingVoucher(true);
    try {
      const { generatePassengerVoucherPDF } = await import("@/lib/generate-voucher");

      // Always fetch fresh booking data so tickets are present even if the cached
      // _booking raced ahead of ticket generation (tickets are written async after
      // the booking is confirmed — see finalizePaymentSuccess in payments.service.ts).
      const freshBooking: BookingWithTicket = await apiClient.get(`/bookings/${bookingId}`);
      const bookingData = freshBooking ?? _booking;

      const activeSchedule = isRoundTrip ? outboundSchedule : selectedSchedule;
      // The server-confirmed settled amount/currency (what was actually charged) is
      // authoritative — prefer it over the ETB booking fare once available. Shown exactly
      // as returned by the API (no /100, no per-passenger split) on every passenger's
      // voucher — see fareIsMajorUnits below.
      const settledAmountMinor = bookingData?.payment?.amountMinor;
      const settledCurrency = bookingData?.payment?.currency;
      const hasSettledAmount = settledAmountMinor != null && !!settledCurrency;
      // Derive display currency from nationality (same logic as review/payment pages)
      const nat = (searchCriteria?.nationality ?? '').toUpperCase();
      const passengerDisplayCurrency = nat === 'DJIBOUTIAN' ? 'DJF' : nat === 'ETHIOPIAN' ? 'ETB' : 'USD';
      const voucherCurrency = hasSettledAmount ? settledCurrency! : passengerDisplayCurrency;
      const createdAt = bookingData?.createdAt || new Date().toISOString();
      const status = bookingData?.status || "CONFIRMED";

      // Compute per-passenger fares (in ETB) using the same logic as the review/payment
      // pages. reviewedPassengerFares is the authoritative source; rebuild from package
      // context as a fallback so free children always show 0 on their voucher.
      const { packageTierPriceMinor } = useBookingStore.getState();
      const isPackageBooking = packageTierPriceMinor != null;
      const adultCount =
        searchCriteria?.adultCount ??
        passengers.filter((p) => !isChild(p)).length;
      const pkgMultiplier = isPackageBooking ? 2 : 1;
      const pkgAdultFare = isPackageBooking
        ? packageTierPriceMinor! * pkgMultiplier
        : 0;
      const pkgChildFare = pkgAdultFare;

      const getEtbFare = (idx: number): number => {
        if (reviewedPassengerFares?.[idx] != null)
          return reviewedPassengerFares[idx].fareMinor;
        if (isPackageBooking) {
          const isPkgChild = idx >= adultCount;
          const isFreeChild = isPkgChild && idx - adultCount < adultCount;
          if (isFreeChild) return 0;
          return isPkgChild ? pkgChildFare : pkgAdultFare;
        }
        const totalFare =
          reviewedTotalMinor ?? paidAmountMinor ?? bookingData?.totalMinor ?? 0;
        return Math.round(totalFare / passengers.length);
      };

      const outbound = {
        trainNumber: activeSchedule?.trainNumber || "N/A",
        trainName: "EDR Express",
        origin: {
          name: activeSchedule?.origin || "Origin",
          code: "ORG",
          city: activeSchedule?.origin || "Origin",
        },
        destination: {
          name: activeSchedule?.destination || "Destination",
          code: "DST",
          city: activeSchedule?.destination || "Destination",
        },
        departureAt: activeSchedule?.departureTime || new Date().toISOString(),
        arrivalAt: activeSchedule?.arrivalTime || new Date().toISOString(),
        seatClass: activeSchedule?.selectedSeatClassName,
      };

      const inbound = inboundSchedule
        ? {
            trainNumber: inboundSchedule.trainNumber || "N/A",
            trainName: "EDR Express",
            origin: {
              name: inboundSchedule.origin,
              code: "ORG",
              city: inboundSchedule.origin,
            },
            destination: {
              name: inboundSchedule.destination,
              code: "DST",
              city: inboundSchedule.destination,
            },
            departureAt:
              inboundSchedule.departureTime || new Date().toISOString(),
            arrivalAt: inboundSchedule.arrivalTime || new Date().toISOString(),
            seatClass: inboundSchedule.selectedSeatClassName,
          }
        : undefined;

      // Separate file per passenger, saved back-to-back with no macrotask (setTimeout)
      // between them — a setTimeout delay would push later saves outside the click's
      // synchronous user-activation window and risk iOS Safari silently blocking them.
      // Build a consumed-ticket set so each ticket is used at most once even when
      // multiple passengers share the same name (e.g. parent + child same surname).
      const remainingTickets = [...(bookingData?.tickets ?? [])];
      const consumeTicket = (name: string, idx: number) => {
        // 1. exact name match
        let ti = remainingTickets.findIndex((t) => t.passengerName === name);
        // 2. case-insensitive match (Verifayda may rewrite casing server-side)
        if (ti === -1) ti = remainingTickets.findIndex((t) => t.passengerName?.toLowerCase() === name.toLowerCase());
        // 3. positional fallback
        if (ti === -1 && idx < remainingTickets.length) ti = idx;
        if (ti === -1) return null;
        return remainingTickets.splice(ti, 1)[0];
      };

      for (let i = 0; i < passengers.length; i++) {
        const p = passengers[i];
        const matchedTicket = consumeTicket(p.name || "", i);
        const ticketNumber = matchedTicket?.barcodePayload || "Not yet issued";

        await generatePassengerVoucherPDF({
          bookingRef:          pnr,
          ticketNumber,
          passengerName:       p.name || `Passenger ${i + 1}`,
          dateOfBirth:         p.dateOfBirth,
          nationality:         p.nationality,
          seatNumber:          p.seatNumber,
          coachNumber:         p.coachNumber,
          outboundSeatNumber:  p.outboundSeatNumber,
          outboundCoachNumber: p.outboundCoachNumber,
          inboundSeatNumber:   p.inboundSeatNumber,
          inboundCoachNumber:  p.inboundCoachNumber,
          status,
          outboundSchedule:    outbound,
          inboundSchedule:     inbound,
          isRoundTrip,
          fareMinor:           hasSettledAmount ? settledAmountMinor! : getEtbFare(i),
          currency:            voucherCurrency,
          fareIsMajorUnits:    hasSettledAmount,
          createdAt,
        });
      }
    } catch (error) {
      alert(
        `Failed to generate voucher: ${error instanceof Error ? error.message : "Unknown error"}`,
      );
    } finally {
      setIsGeneratingVoucher(false);
    }
  };

  const handleNewBooking = () => {
    clearBooking();
    window.location.href = "/";
  };

  useEffect(() => {
    if (!bookingId || !pnr) {
      window.location.href = "/";
    }
  }, [bookingId, pnr, router]);

  if (!bookingId || !pnr) return null;

  // Wait for the actual booking status before deciding pending vs. confirmed —
  // without this, _booking is briefly undefined on first load, isConfirmed reads
  // as false, and the page flashes "payment pending" before flipping to
  // "confirmed" once the fetch resolves (common, since the payment webhook has
  // often already completed by the time the user lands here). Also keep showing
  // this same spinner through the grace period above if the booking is still
  // PENDING_PAYMENT — most of the time the webhook lands within that window, so
  // the user goes straight to "confirmed" without ever seeing "pending" at all.
  if (isBookingLoading || (withinGracePeriod && _booking?.status === "PENDING_PAYMENT")) {
    return (
      <div className="booking-page">
        <div className="container mx-auto px-4">
          <div className="max-w-6xl mx-auto flex flex-col items-center justify-center py-24 text-center">
            <div className="w-12 h-12 rounded-full border-4 border-primary/20 border-t-primary animate-spin mb-4" />
            <p className="text-gray-600 dark:text-gray-400">
              Please wait, we are processing your booking…
            </p>
          </div>
        </div>
      </div>
    );
  }

  // A real fetch failure (not just "still pending") — surface it honestly instead of
  // silently pretending the booking is pending, and let the user retry the check
  // without needing a full page refresh.
  if (isBookingError) {
    return (
      <div className="booking-page">
        <div className="container mx-auto px-4">
          <div className="max-w-6xl mx-auto flex flex-col items-center justify-center py-24 text-center">
            <p className="text-gray-600 dark:text-gray-400 mb-4">
              We&apos;re having trouble loading your booking status right
              now. This is usually temporary — tap below to try again.
            </p>
            <button
              onClick={() => refetchBooking()}
              className="btn-primary"
            >
              Check again
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="booking-page">
      <div className="container mx-auto px-4">
        <div className="max-w-6xl mx-auto">
          {/* Success Header */}
          <div className="text-center mb-8">
            <div className="flex justify-center mb-4">
              {isConfirmed ? (
                <div className="w-20 h-20 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center animate-bounce">
                  <CheckCircle className="w-12 h-12 text-green-600 dark:text-green-400" />
                </div>
              ) : (
                <div className="w-20 h-20 bg-amber-100 dark:bg-amber-900/30 rounded-full flex items-center justify-center">
                  <Clock className="w-12 h-12 text-amber-600 dark:text-amber-400" />
                </div>
              )}
            </div>
            {isConfirmed ? (
              <>
                <h1 className="text-4xl font-bold text-green-600 dark:text-green-400 mb-2">
                  {packageName
                    ? `${packageName} booking confirmed!`
                    : "Booking confirmed!"}
                </h1>
                <p className="text-gray-600 dark:text-gray-400 text-lg">
                  Your train tickets are ready
                </p>
              </>
            ) : (
              <>
                <h1 className="text-4xl font-bold text-amber-600 dark:text-amber-400 mb-2">
                  Booking received — payment pending
                </h1>
                <p className="text-gray-600 dark:text-gray-400 text-lg">
                  We haven&apos;t confirmed your payment yet. Your tickets will
                  be issued once payment is completed.
                </p>
              </>
            )}
          </div>

          {/* PNR Card */}
          <div className="card mb-6 bg-primary text-white">
            <div className="text-center">
              <p className="text-sm font-medium mb-2">
                Booking reference (PNR)
              </p>
              <div className="flex items-center justify-center gap-3">
                <span className="text-5xl font-bold tracking-widest">
                  {pnr}
                </span>
                <button
                  onClick={copyPNR}
                  className="p-2 hover:bg-white hover:bg-opacity-20 rounded transition-colors"
                  title="Copy PNR"
                >
                  {copied ? (
                    <CheckCircle className="w-6 h-6" />
                  ) : (
                    <Copy className="w-6 h-6" />
                  )}
                </button>
              </div>
              <p className="text-sm font-medium mt-2">
                Save this reference number for future use
              </p>
            </div>
          </div>

          {/* Trip Details */}
          <div className="card mb-6">
            <div>
              <div className="flex items-center gap-3 mb-4">
                <div className="w-10 h-10 bg-primary-100 dark:bg-primary-900/30 rounded-lg flex items-center justify-center">
                  <Train className="w-6 h-6 text-primary dark:text-primary-400" />
                </div>
                <h2 className="text-2xl font-semibold text-gray-900 dark:text-gray-100">
                  {isRoundTrip ? "Round trip details" : "Trip details"}
                </h2>
              </div>

              {/* Outbound journey (round trip) or single journey */}
              {(() => {
                const schedule = isRoundTrip
                  ? outboundSchedule
                  : selectedSchedule;
                if (!schedule) return null;
                return (
                  <div className="mb-4">
                    {isRoundTrip && (
                      <p className="text-xs font-bold uppercase tracking-wide text-primary mb-2">
                        Outbound
                      </p>
                    )}
                    <div className="grid md:grid-cols-2 gap-4">
                      <div className="space-y-3">
                        <div>
                          <p className="text-sm text-gray-600 dark:text-gray-400">
                            Train number
                          </p>
                          <p className="font-semibold text-lg text-gray-900 dark:text-gray-100">
                            {schedule.trainNumber}
                          </p>
                        </div>
                        <div>
                          <p className="text-sm text-gray-600 dark:text-gray-400">
                            Route
                          </p>
                          <p className="font-semibold text-lg text-gray-900 dark:text-gray-100">
                            {schedule.origin} → {schedule.destination}
                          </p>
                        </div>
                        {schedule.selectedSeatClassName && (
                          <div>
                            <p className="text-sm text-gray-600 dark:text-gray-400">
                              Class
                            </p>
                            <p className="font-semibold text-gray-900 dark:text-gray-100">
                              {schedule.selectedSeatClassName.replace(
                                /_/g,
                                " ",
                              )}
                            </p>
                          </div>
                        )}
                      </div>
                      <div className="space-y-3">
                        <div>
                          <p className="text-sm text-gray-600 dark:text-gray-400">
                            Departure
                          </p>
                          <p className="font-semibold text-gray-900 dark:text-gray-100">
                            {schedule.departureTime &&
                              format(toZonedDate(new Date(schedule.departureTime)), "PPp")}
                          </p>
                        </div>
                        <div>
                          <p className="text-sm text-gray-600 dark:text-gray-400">
                            Arrival
                          </p>
                          <p className="font-semibold text-gray-900 dark:text-gray-100">
                            {schedule.arrivalTime &&
                              format(toZonedDate(new Date(schedule.arrivalTime)), "PPp")}
                          </p>
                        </div>
                        <div>
                          <p className="text-sm text-gray-600 dark:text-gray-400">
                            Duration
                          </p>
                          <p className="font-semibold text-gray-900 dark:text-gray-100">
                            {schedule.duration}
                          </p>
                        </div>
                      </div>
                    </div>
                  </div>
                );
              })()}

              {/* Return journey (round trip only) */}
              {isRoundTrip && inboundSchedule && (
                <div className="border-t border-dashed border-gray-200 dark:border-gray-700 pt-4">
                  <p className="text-xs font-bold uppercase tracking-wide text-blue-500 mb-2">
                    Return
                  </p>
                  <div className="grid md:grid-cols-2 gap-4">
                    <div className="space-y-3">
                      <div>
                        <p className="text-sm text-gray-600 dark:text-gray-400">
                          Train number
                        </p>
                        <p className="font-semibold text-lg text-gray-900 dark:text-gray-100">
                          {inboundSchedule.trainNumber}
                        </p>
                      </div>
                      <div>
                        <p className="text-sm text-gray-600 dark:text-gray-400">
                          Route
                        </p>
                        <p className="font-semibold text-lg text-gray-900 dark:text-gray-100">
                          {inboundSchedule.origin} →{" "}
                          {inboundSchedule.destination}
                        </p>
                      </div>
                      {inboundSchedule.selectedSeatClassName && (
                        <div>
                          <p className="text-sm text-gray-600 dark:text-gray-400">
                            Class
                          </p>
                          <p className="font-semibold text-gray-900 dark:text-gray-100">
                            {inboundSchedule.selectedSeatClassName.replace(
                              /_/g,
                              " ",
                            )}
                          </p>
                        </div>
                      )}
                    </div>
                    <div className="space-y-3">
                      <div>
                        <p className="text-sm text-gray-600 dark:text-gray-400">
                          Departure
                        </p>
                        <p className="font-semibold text-gray-900 dark:text-gray-100">
                          {inboundSchedule.departureTime &&
                            format(
                              toZonedDate(new Date(inboundSchedule.departureTime)),
                              "PPp",
                            )}
                        </p>
                      </div>
                      <div>
                        <p className="text-sm text-gray-600 dark:text-gray-400">
                          Arrival
                        </p>
                        <p className="font-semibold text-gray-900 dark:text-gray-100">
                          {inboundSchedule.arrivalTime &&
                            format(
                              toZonedDate(new Date(inboundSchedule.arrivalTime)),
                              "PPp",
                            )}
                        </p>
                      </div>
                      <div>
                        <p className="text-sm text-gray-600 dark:text-gray-400">
                          Duration
                        </p>
                        <p className="font-semibold text-gray-900 dark:text-gray-100">
                          {inboundSchedule.duration}
                        </p>
                      </div>
                    </div>
                  </div>
                </div>
              )}
            </div>
          </div>

          {/* Booking date & payment summary */}
          <div className="card mb-6">
            <h2 className="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
              Booking details
            </h2>
            <div className="grid sm:grid-cols-2 gap-4">
              <div>
                <p className="text-sm text-gray-600 dark:text-gray-400">
                  Booking date
                </p>
                <p className="font-semibold text-gray-900 dark:text-gray-100">
                  {format(new Date(_booking?.createdAt || new Date()), "PPp")}
                </p>
              </div>
              <div>
                <p className="text-sm text-gray-600 dark:text-gray-400">
                  Status
                </p>
                <p
                  className={`font-semibold ${isConfirmed ? "text-green-600 dark:text-green-400" : "text-amber-600 dark:text-amber-400"}`}
                >
                  {_booking?.status || "PENDING_PAYMENT"}
                </p>
              </div>
              <div>
                <p className="text-sm text-gray-600 dark:text-gray-400">
                  Passengers
                </p>
                <p className="font-semibold text-gray-900 dark:text-gray-100">
                  {passengers.length}
                </p>
              </div>
              <div>
                <p className="text-sm text-gray-600 dark:text-gray-400">
                  Total paid
                </p>
                <p className="font-semibold text-gray-900 dark:text-gray-100">
                  {(() => {
                    // The server-confirmed settled amount is authoritative — prefer it over
                    // any client-side session state, which can go stale (e.g. after a refresh).
                    if (_booking?.payment?.amountMinor != null) {
                      return `${_booking.payment.currency || 'ETB'} ${(_booking.payment.amountMinor / 100).toFixed(2)}`;
                    }
                    if (reviewedTotalMinor != null)
                      return `${paidCurrency || 'ETB'} ${(reviewedTotalMinor / 100).toFixed(2)}`;
                    if (paidAmountMinor != null)
                      return `${paidCurrency || 'ETB'} ${(paidAmountMinor / 100).toFixed(2)}`;
                    if (_booking?.totalMinor != null)
                      return `ETB ${(_booking.totalMinor / 100).toFixed(2)}`;
                    return 'ETB 0.00';
                  })()}
                </p>
              </div>
            </div>
          </div>

          {/* Tickets */}
          <div className="mb-6">
            <h2 className="text-2xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
              Your tickets
            </h2>
            <div className="space-y-4">
              {passengers.map((passenger, index) => {
                // Match by name first (tickets aren't necessarily created/ordered the same
                // way as this passengers array) — fall back to position if no name match.
                const backendTicket =
                  _booking?.tickets?.find(
                    (t) => t.passengerName === passenger.name,
                  ) ??
                  _booking?.tickets?.[index] ??
                  null;
                // No fabricated placeholder — a made-up TKT-... number reads as real and is
                // misleading if it doesn't match what's actually on file.
                const ticketNumber = isConfirmed
                  ? backendTicket?.barcodePayload || null
                  : null;

                return (
                  <div
                    key={index}
                    className="card hover:shadow-lg transition-shadow"
                  >
                    {/* Ticket Info */}
                    <div className="flex-1">
                      <div className="flex items-start justify-between mb-4">
                        <div>
                          <h3 className="text-xl font-bold text-gray-900 dark:text-gray-100">
                            {passenger.name}
                          </h3>
                          <p className="text-sm text-gray-600 dark:text-gray-400">
                            Passenger {index + 1}
                          </p>
                        </div>
                        {isConfirmed ? (
                          <span className="badge badge-success">CONFIRMED</span>
                        ) : (
                          <span className="badge badge-warning">
                            AWAITING PAYMENT
                          </span>
                        )}
                      </div>

                      <div className="grid grid-cols-2 gap-4 text-sm">
                        <div>
                          <p className="text-gray-600 dark:text-gray-400">
                            Ticket Number
                          </p>
                          <p className="font-semibold text-gray-900 dark:text-gray-100">
                            {ticketNumber ||
                              (isConfirmed
                                ? "Not yet issued"
                                : "Pending payment")}
                          </p>
                        </div>
                        <div>
                          <p className="text-gray-600 dark:text-gray-400">
                            Date of Birth
                          </p>
                          <p className="font-semibold text-gray-900 dark:text-gray-100">
                            {format(new Date(passenger.dateOfBirth), "PP")}
                          </p>
                        </div>
                        <div>
                          <p className="text-gray-600 dark:text-gray-400">
                            Nationality
                          </p>
                          <p className="font-semibold text-gray-900 dark:text-gray-100">
                            {passenger.nationality}
                          </p>
                        </div>
                        <div>
                          <p className="text-gray-600 dark:text-gray-400">
                            Seat(s)
                          </p>
                          {(() => {
                            const adultCount =
                              searchCriteria?.adultCount ??
                              passengers.filter((p) => !isChild(p)).length;
                            const isFreeChild = packageId
                              ? index >= adultCount &&
                                index - adultCount < adultCount
                              : isChild(passenger) &&
                                isFirstChild(passengers, index);
                            if (isFreeChild)
                              return (
                                <p className="font-semibold text-gray-900 dark:text-gray-100">
                                  —
                                </p>
                              );
                            return isRoundTrip ? (
                              <div className="space-y-0.5">
                                <p className="font-semibold text-gray-900 dark:text-gray-100">
                                  Outbound:{" "}
                                  {(passenger as any).outboundCoachNumber && (
                                    <span className="text-xs text-gray-500 dark:text-gray-400 ml-1">
                                      {(passenger as any).outboundCoachNumber}
                                    </span>
                                  )}{" "}
                                  —{" "}
                                  {(passenger as any).outboundSeatNumber ||
                                    "Auto-assigned at boarding"}
                                </p>
                                <p className="font-semibold text-gray-900 dark:text-gray-100">
                                  Return:{" "}
                                  {(passenger as any).inboundCoachNumber && (
                                    <span className="text-xs text-gray-500 dark:text-gray-400 ml-1">
                                      {(passenger as any).inboundCoachNumber}
                                    </span>
                                  )}{" "}
                                  —{" "}
                                  {(passenger as any).inboundSeatNumber ||
                                    "Auto-assigned at boarding"}
                                </p>
                              </div>
                            ) : (
                              <p className="font-semibold text-gray-900 dark:text-gray-100">
                                {passenger.coachNumber && (
                                  <span className="text-xs text-gray-500 dark:text-gray-400 ml-1">
                                    (Coach {passenger.coachNumber})
                                  </span>
                                )}{" "}
                                —{" "}
                                {passenger.seatNumber ||
                                  "Auto-assigned at boarding"}
                              </p>
                            );
                          })()}
                        </div>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>

          {/* Action Buttons — voucher/ticket only makes sense once the booking is
              actually confirmed; a pending-payment booking has no real ticket yet. */}
          {isConfirmed && (
            <div className="mb-6">
              <button
                onClick={handleDownloadVoucher}
                disabled={isGeneratingVoucher}
                className="btn-primary w-full flex items-center justify-center gap-2 relative"
              >
                {isGeneratingVoucher ? (
                  <>
                    <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
                    <span>Generating...</span>
                  </>
                ) : (
                  <>
                    <FileText className="w-4 h-4" />
                    <span>Download Voucher</span>
                  </>
                )}
              </button>
            </div>
          )}

          {/* New Booking Button */}
          <button
            onClick={handleNewBooking}
            className="btn-primary w-full py-4 text-lg font-semibold"
          >
            Book another trip
          </button>

          {/* Info Notices */}
          <div className="mt-6 space-y-3">
            <div className="p-4 bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 rounded-lg">
              <p className="text-sm text-blue-800 dark:text-blue-300">
                📧 A confirmation email with your tickets has been sent to your
                registered email address.
              </p>
            </div>
            <div className="p-4 bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-800 rounded-lg">
              <p className="text-sm text-green-800 dark:text-green-300">
                ✅ Please arrive at the station at least 2 hours before
                departure.
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
