"use client";

import { Suspense } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import { useQuery, useMutation } from "@tanstack/react-query";
import { apiClient } from "@/lib/api-client";
import { useEffect, useState } from "react";
import {
  Clock,
  Users,
  CheckCircle2,
  AlertCircle,
  Download,
  Copy,
  Check,
  CreditCard,
  Wallet,
  Smartphone,
  Loader2,
  ChevronLeft,
  X,
} from "lucide-react";
import { format } from "date-fns";
import { formatTime, getTimePeriod, toZonedDate } from "@/utils/format";
import { formatFare } from "@/utils/fare-utils";
import {
  markManageBookingPaymentReturn,
  consumeManageBookingPaymentReturn,
} from "@/utils/manage-booking-return";

// Derive display currency from the booking record's own displayCurrency field
// (set at booking creation from the passenger's nationality). Falls back to ETB.
function getBookingDisplayCurrency(booking: any): string {
  return booking?.displayCurrency || 'ETB';
}

const getIconForMethod = (methodType: string) => {
  if (methodType.includes("CARD")) return CreditCard;
  if (methodType.includes("WALLET")) return Wallet;
  return Smartphone;
};

function SeatDetailsGrid({
  seat,
}: {
  seat?: { coach?: string; number?: string; seatClass?: string };
}) {
  return (
    <div className="grid grid-cols-2 gap-3 text-sm">
      <div>
        <span className="text-gray-500 dark:text-gray-400">Coach:</span>
        <div className="font-mono font-semibold text-gray-900 dark:text-white">
          {seat?.coach || "N/A"}
        </div>
      </div>
      <div>
        <span className="text-gray-500 dark:text-gray-400">Seat Number:</span>
        <div className="font-semibold text-gray-900 dark:text-white">
          {seat?.number || "N/A"}
        </div>
      </div>
      <div className="col-span-2">
        <span className="text-gray-500 dark:text-gray-400">Class:</span>
        <div className="font-medium text-gray-900 dark:text-white">
          {seat?.seatClass || "N/A"}
        </div>
      </div>
    </div>
  );
}

function BookingDetailContent() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const bookingRef =
    searchParams.get("ref") ||
    searchParams.get("bookingRef") ||
    searchParams.get("pnr");

  // Mirrors /booking/payment's state shape: selectedMethod is the PaymentMethod `type`
  // (used both for lookup and to decide provider-specific redirect handling), not the id.
  const [selectedMethod, setSelectedMethod] = useState<string | null>(null);
  const [selectedMethodCurrency, setSelectedMethodCurrency] = useState<
    string | null
  >(null);
  const [paymentError, setPaymentError] = useState<string | null>(null);
  // The mobile Pay trigger opens this modal instead of living in a `fixed bottom-0`
  // bar — that bar kept getting covered by the phone's own home-indicator/gesture
  // nav bar. The modal's footer button is a normal in-flow flex item instead, so it
  // can't end up pinned underneath system chrome.
  const [paymentModalOpen, setPaymentModalOpen] = useState(false);
  const [copiedPNR, setCopiedPNR] = useState(false);
  const [isGeneratingVoucher, setIsGeneratingVoucher] = useState(false);

  // 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,
    isLoading,
    error,
    refetch,
  } = useQuery({
    queryKey: ["booking-detail", bookingRef],
    queryFn: async () => {
      if (!bookingRef) throw new Error("No booking reference provided");
      const response = await apiClient.get(`/bookings/${bookingRef}`);
      // Handle wrapped response
      return (response as any)?.data || response;
    },
    enabled: !!bookingRef,
    retry: 1,
  });

  // When the booking is CONFIRMED but has no tickets (generate failed silently at
  // payment time), call generate now so tickets are ready before the user clicks Download.
  useEffect(() => {
    if (
      booking?.status === 'CONFIRMED' &&
      booking?.id &&
      Array.isArray(booking?.tickets) &&
      booking.tickets.length === 0
    ) {
      apiClient.post(`/tickets/generate/${booking.id}`, {}).then(() => refetch()).catch(() => {});
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [booking?.id, booking?.status, booking?.tickets?.length]);

  const { data: paymentMethods } = useQuery<any[]>({
    queryKey: ["payment-methods"],
    queryFn: () => apiClient.get("/payments/methods"),
    enabled:
      booking?.status === "PENDING_PAYMENT" || booking?.status === "DRAFT",
  });

  // When the booking is PENDING_PAYMENT, poll the payment intent endpoint every 10 s.
  // The backend auto-confirms the booking when it finds a SUCCEEDED intent, so detecting
  // SUCCEEDED here means the booking is now CONFIRMED — refetch to update the UI.
  const { data: intentStatus } = useQuery<any>({
    queryKey: ["payment-intent-status", booking?.id],
    queryFn: () => apiClient.get(`/payments/intents/${booking!.id}`),
    enabled: booking?.status === "PENDING_PAYMENT" && !!booking?.id,
    refetchInterval: 10_000,
  });

  useEffect(() => {
    if (intentStatus?.status === "SUCCEEDED") {
      refetch();
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [intentStatus?.status]);

  const selectedPaymentMethod =
    (paymentMethods || []).find((m: any) => m.type === selectedMethod) || null;

  const displayCurrency = getBookingDisplayCurrency(booking);

  // Same conversion logic as /booking/payment: only hit the booking-amount-changer API
  // when the selected method actually settles in a different currency than the booking's display currency.
  const isConversionNeeded =
    !!selectedMethodCurrency && selectedMethodCurrency !== displayCurrency;
  const amountCurrency = isConversionNeeded
    ? selectedMethodCurrency!
    : displayCurrency;

  const { data: bookingAmountData, isLoading: loadingAmount } = useQuery<{
    amount: number;
    currency: string;
    booking_id: string;
  }>({
    queryKey: ["bookingAmount", booking?.id, amountCurrency],
    queryFn: async () => {
      const url = `/payments/booking-amount?bookingId=${booking?.id}&currency=${amountCurrency}`;
      const response: any = await apiClient.get(url);
      return response;
    },
    enabled: !!booking?.id && isConversionNeeded,
  });

  const totalAmountDisplay = isConversionNeeded
    ? bookingAmountData != null
      ? bookingAmountData.amount
      : null
    : (booking?.displayTotalMinor ?? booking?.totalMinor ?? 0) / 100;
  const confirmedCurrency = isConversionNeeded
    ? bookingAmountData?.currency || amountCurrency
    : displayCurrency;
  const awaitingAmount =
    isConversionNeeded && loadingAmount && totalAmountDisplay === null;

  const paymentMutation = useMutation({
    mutationFn: async (data: any) => {
      return await apiClient.post("/payments/initiate", {
        bookingId: data.bookingId,
        method: data.method,
        paymentMethodId: data.paymentMethodId,
        platform: "web",
      });
    },
    onSuccess: async (data: any) => {
      setPaymentError(null);

      if (
        (selectedMethod === "TELEBIRR" || selectedMethod === "WAAFI") &&
        data?.clientAction?.type === "REDIRECT"
      ) {
        window.location.href = data.clientAction.url;
        return;
      }

      // No redirect needed (e.g. WALLET) — the marker set in handlePayment is now moot.
      consumeManageBookingPaymentReturn();
      await refetch();
    },
    onError: (error: any) => {
      setPaymentError(
        error?.response?.data?.message ||
          error?.message ||
          "Payment failed. Please try again.",
      );
    },
  });

  const handlePayment = () => {
    if (!selectedMethod || !booking?.id) {
      setPaymentError("Please select a payment method");
      return;
    }

    if (!selectedPaymentMethod) {
      setPaymentError("Invalid payment method selected");
      return;
    }

    setPaymentError(null);
    // Flag this as a Manage Booking payment so the gateway's success/failure return page
    // sends the user back here instead of the new-booking confirmation flow.
    markManageBookingPaymentReturn(booking.bookingRef);
    paymentMutation.mutate({
      bookingId: booking.id,
      method: selectedMethod,
      paymentMethodId: selectedPaymentMethod.id,
    });
  };

  const copyPNR = () => {
    if (booking?.bookingRef) {
      navigator.clipboard.writeText(booking.bookingRef);
      setCopiedPNR(true);
      setTimeout(() => setCopiedPNR(false), 2000);
    }
  };

  const handleDownloadVoucher = async () => {
    if (!booking || !booking.bookingRef) {
      alert("Booking data not available. Please try again.");
      return;
    }
    setIsGeneratingVoucher(true);
    try {
      // Always fetch fresh booking data so tickets are included.
      const fresh = await apiClient.get<any>(`/bookings/${booking.bookingRef}`);
      const bookingData = (fresh as any)?.data || fresh;
      const { generateVoucherPDF } = await import("@/lib/generate-voucher");
      await generateVoucherPDF(bookingData as any);
    } catch (error) {
      alert(
        `Failed to generate voucher: ${error instanceof Error ? error.message : "Unknown error"}`,
      );
    } finally {
      setIsGeneratingVoucher(false);
    }
  };

  if (isLoading) {
    return (
      <div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center p-4">
        <div className="bg-white dark:bg-gray-800 rounded-2xl p-8 text-center max-w-md w-full">
          <div className="w-16 h-16 border-4 border-primary border-t-transparent rounded-full animate-spin mx-auto mb-4" />
          <h2 className="text-xl font-bold text-gray-900 dark:text-white mb-2">
            Loading Booking Details
          </h2>
          <p className="text-sm text-gray-500 dark:text-gray-400">
            Fetching your booking information...
          </p>
        </div>
      </div>
    );
  }

  if (error || !booking) {
    return (
      <div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center p-4">
        <div className="bg-white dark:bg-gray-800 rounded-2xl p-8 text-center max-w-md w-full">
          <div className="w-16 h-16 bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
            <AlertCircle className="w-8 h-8 text-red-500" />
          </div>
          <h2 className="text-xl font-bold text-gray-900 dark:text-white mb-2">
            Booking Not Found
          </h2>
          <p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
            {!bookingRef
              ? "No booking reference provided in the URL."
              : `Unable to find booking with reference: ${bookingRef}`}
          </p>
          <button onClick={() => refetch()} className="btn-secondary mb-2">
            Try Again
          </button>
          <button
            onClick={() => router.push("/booking/search")}
            className="btn-primary"
          >
            New Booking
          </button>
        </div>
      </div>
    );
  }

  const isPendingPayment =
    booking.status === "PENDING_PAYMENT" || booking.status === "DRAFT";
  const isConfirmed =
    booking.status === "TICKETED" || booking.status === "CONFIRMED";
  const isExpired = booking.status === "EXPIRED";
  const isCancelled = booking.status === "CANCELLED";

  const StatusBadge = () => {
    const statusConfig = {
      PENDING_PAYMENT: {
        color:
          "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400",
        label: "Pending Payment",
      },
      DRAFT: {
        color:
          "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400",
        label: "Pending Payment",
      },
      CONFIRMED: {
        color:
          "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
        label: "Confirmed",
      },
      TICKETED: {
        color:
          "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
        label: "Ticketed",
      },
      EXPIRED: {
        color: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",
        label: "Expired",
      },
      CANCELLED: {
        color: "bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300",
        label: "Cancelled",
      },
    };

    const config =
      statusConfig[booking.status as keyof typeof statusConfig] ||
      statusConfig.DRAFT;

    return (
      <span
        className={`inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-sm font-semibold ${config.color}`}
      >
        {isConfirmed && <CheckCircle2 className="w-4 h-4" />}
        {config.label}
      </span>
    );
  };

  // /bookings/:ref returns one row per passenger PER LEG for round trips (leg 1 =
  // outbound, leg 2 = return), each carrying that leg's own seat assignment —
  // /booking/payment's fare breakdown, by contrast, shows one combined row per
  // passenger with an Outbound/Return sub-split. Group leg rows back together here —
  // by identity, not by row — so every consumer (fare breakdown, passenger/seat list)
  // sees one entry per real passenger with both legs' seats attached, not a doubled
  // list of half-passenger rows.
  const isRoundTripBooking = booking.bookingType === "ROUND_TRIP";
  const groupedPassengers = (() => {
    const rows: any[] = booking.passengers || [];
    if (!isRoundTripBooking) {
      return rows.map((p) => ({
        fullName: p.fullName,
        category: p.category,
        fareMinor: p.fareMinor ?? 0,
        outboundSeat: p.seat,
        returnSeat: undefined as any,
      }));
    }
    const grouped = new Map<
      string,
      {
        fullName: string;
        category: string;
        outboundFareMinor: number;
        returnFareMinor: number;
        outboundSeat?: any;
        returnSeat?: any;
      }
    >();
    rows.forEach((p) => {
      const key = `${p.fullName}|${p.dateOfBirth}|${p.category}`;
      const entry = grouped.get(key) || {
        fullName: p.fullName,
        category: p.category,
        outboundFareMinor: 0,
        returnFareMinor: 0,
        outboundSeat: undefined,
        returnSeat: undefined,
      };
      if (p.leg === 2) {
        entry.returnFareMinor = p.fareMinor ?? 0;
        entry.returnSeat = p.seat;
      } else {
        entry.outboundFareMinor = p.fareMinor ?? 0;
        entry.outboundSeat = p.seat;
      }
      grouped.set(key, entry);
    });
    return Array.from(grouped.values()).map((p) => ({
      fullName: p.fullName,
      category: p.category,
      fareMinor: p.outboundFareMinor + p.returnFareMinor,
      outboundFareMinor: p.outboundFareMinor,
      returnFareMinor: p.returnFareMinor,
      outboundSeat: p.outboundSeat,
      returnSeat: p.returnSeat,
    }));
  })();

  // Scale per-passenger ETB fareMinor to the booking's display currency using the
  // ratio of displayTotalMinor / totalMinor. Falls back to 1 (ETB) when not available.
  const fareScaleFactor = (() => {
    const etbTotal = booking?.totalMinor;
    const displayTotal = booking?.displayTotalMinor;
    if (!etbTotal || !displayTotal || etbTotal === displayTotal) return 1;
    return displayTotal / etbTotal;
  })();

  // Flight-style origin → train → destination timeline for a single leg's schedule.
  // Shared by both the pending-payment "Trip Summary" card and the confirmed booking's
  // "Journey Details" card so a round trip's outbound and return legs render identically —
  // each of those cards calls this once per leg instead of hardcoding booking.schedule only.
  const renderJourneyTimeline = (schedule: any) => (
    <div className="flex">
      <div className="flex flex-col items-center w-8 flex-shrink-0">
        <div className="w-4 h-4 rounded-full border-4 border-primary bg-white dark:bg-gray-900 z-10" />
        <div className="w-0.5 flex-1 bg-gradient-to-b from-primary via-gray-300 dark:via-gray-700 to-gray-300 dark:to-gray-700 my-2" />
        <div className="w-4 h-4 rounded-full border-4 border-gray-400 dark:border-gray-600 bg-white dark:bg-gray-900 z-10" />
      </div>
      <div className="flex-1 flex flex-col">
        <div className="pb-8">
          <div className="text-2xl font-bold text-gray-900 dark:text-white">
            {schedule?.departureAt ? formatTime(schedule.departureAt) : "--:--"}
          </div>
          <div className="text-sm text-gray-500 dark:text-gray-400 mt-0.5">
            {schedule?.departureAt
              ? `${format(toZonedDate(new Date(schedule.departureAt)), "EEE, MMM d")} · ${getTimePeriod(schedule.departureAt)}`
              : "N/A"}
          </div>
          <div className="text-base font-semibold text-gray-900 dark:text-white mt-2">
            {schedule?.origin?.name}
          </div>
          <div className="text-sm text-gray-500 dark:text-gray-400">
            {schedule?.origin?.city}
          </div>
        </div>

        <div className="pb-8">
          <div className="flex items-center gap-6 text-sm text-gray-600 dark:text-gray-400">
            <div className="flex items-center gap-1.5">
              <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M13 10V3L4 14h7v7l9-11h-7z"
                />
              </svg>
              <span className="font-medium">Train {schedule?.trainNumber}</span>
            </div>
          </div>
        </div>

        <div>
          <div className="text-2xl font-bold text-gray-900 dark:text-white">
            {schedule?.arrivalAt ? formatTime(schedule.arrivalAt) : "--:--"}
          </div>
          <div className="text-sm text-gray-500 dark:text-gray-400 mt-0.5">
            {schedule?.arrivalAt
              ? `${format(toZonedDate(new Date(schedule.arrivalAt)), "EEE, MMM d")} · ${getTimePeriod(schedule.arrivalAt)}`
              : "N/A"}
          </div>
          <div className="text-base font-semibold text-gray-900 dark:text-white mt-2">
            {schedule?.destination?.name}
          </div>
          <div className="text-sm text-gray-500 dark:text-gray-400">
            {schedule?.destination?.city}
          </div>
        </div>
      </div>
    </div>
  );

  // Renders one or both legs' timelines with an "Outbound Journey"/"Return Journey"
  // heading pair when the booking has a return leg, or a single "Your Journey" heading
  // for one-way bookings — used by both the pending-payment and confirmed views.
  const renderJourneyLegs = () => (
    <>
      <div className="flex items-center gap-2 mb-4">
        <div className="w-2 h-2 bg-primary rounded-full" />
        <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">
          {isRoundTripBooking ? "Outbound Journey" : "Your Journey"}
        </span>
        {booking.passengers?.[0]?.seat?.seatClass && (
          <span className="ml-auto text-xs px-2 py-0.5 bg-primary/10 text-primary rounded-full font-medium">
            {booking.passengers[0].seat.seatClass}
          </span>
        )}
      </div>
      {renderJourneyTimeline(booking.schedule)}

      {isRoundTripBooking && booking.returnSchedule && (
        <div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
          <div className="flex items-center gap-2 mb-4">
            <div className="w-2 h-2 bg-primary rounded-full" />
            <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">
              Return Journey
            </span>
          </div>
          {renderJourneyTimeline(booking.returnSchedule)}
        </div>
      )}
    </>
  );

  // Order summary card — mirrors /booking/payment's OrderSummary: fare breakdown per
  // passenger, Total with a loading spinner while a currency conversion is in flight, and
  // a note confirming what will actually be charged once a payment method is selected.
  const OrderSummary = () => (
    <div className="card space-y-4">
      <h2 className="text-base font-bold text-gray-900 dark:text-gray-100 pb-2 border-b border-gray-100 dark:border-gray-800">
        Order summary
        <span className="ml-2 text-xs font-normal text-gray-500 dark:text-gray-400">
          Ref:{" "}
          <span className="font-bold text-gray-900 dark:text-gray-100">
            {booking.bookingRef}
          </span>
        </span>
      </h2>

      {!booking.isPackageBooking && booking.bookingType !== "PACKAGE" && (
      <div className="space-y-2">
        <h3 className="text-sm font-bold text-gray-900 dark:text-gray-100">
          Fare breakdown
        </h3>
        {groupedPassengers.map((passenger: any, idx: number) => {
          const isChildPassenger = passenger.category === "CHILD";
          const isFreeChild =
            isChildPassenger && (passenger.fareMinor ?? 0) === 0;
          return (
            <div
              key={idx}
              className="border-b border-gray-100 dark:border-gray-800 pb-2 last:border-0"
            >
              <div className="flex justify-between mb-0.5">
                <span className="text-sm font-medium text-gray-900 dark:text-gray-100 truncate max-w-[60%]">
                  {passenger.fullName || `Passenger ${idx + 1}`}
                  {isChildPassenger && (
                    <span
                      className={`text-xs font-semibold ml-1 ${isFreeChild ? "text-green-600" : "text-blue-600"}`}
                    >
                      ({isFreeChild ? "CHILD - FREE" : "CHILD - FULL FARE"})
                    </span>
                  )}
                </span>
                <span className="text-sm font-semibold text-gray-900 dark:text-gray-100">
                  {formatFare(Math.round((passenger.fareMinor ?? 0) * fareScaleFactor), displayCurrency)}
                </span>
              </div>
              {isRoundTripBooking && !isFreeChild && (
                <div className="pl-3 space-y-0.5 text-xs text-gray-500 dark:text-gray-400">
                  <div className="flex justify-between">
                    <span>Outbound</span>
                    <span>
                      {formatFare(
                        Math.round((passenger.outboundFareMinor ?? 0) * fareScaleFactor),
                        displayCurrency,
                      )}
                    </span>
                  </div>
                  <div className="flex justify-between">
                    <span>Return</span>
                    <span>
                      {formatFare(
                        Math.round((passenger.returnFareMinor ?? 0) * fareScaleFactor),
                        displayCurrency,
                      )}
                    </span>
                  </div>
                </div>
              )}
            </div>
          );
        })}
      </div>
      )}

      <div className="pt-2 border-t-2 border-gray-200 dark:border-gray-700">
        <div className="flex justify-between items-center">
          <span className="font-bold text-gray-900 dark:text-gray-100">
            Total
          </span>
          <span className="text-xl font-bold text-primary flex items-center gap-1.5">
            {awaitingAmount ? (
              <Loader2 className="w-4 h-4 animate-spin text-primary" />
            ) : (
              <>
                {confirmedCurrency} {(totalAmountDisplay ?? 0).toFixed(2)}
              </>
            )}
          </span>
        </div>
        {selectedPaymentMethod && !awaitingAmount && (
          <p className="text-xs text-gray-500 dark:text-gray-400 text-right mt-1">
            You will be charged {confirmedCurrency}{" "}
            {(totalAmountDisplay ?? 0).toFixed(2)} via{" "}
            {selectedPaymentMethod.displayName}
          </p>
        )}
      </div>

      {/* Pay + back buttons — desktop sidebar only */}
      <div className="hidden lg:flex flex-col gap-2 pt-1">
        {paymentError && (
          <p className="text-red-600 dark:text-red-400 text-xs">
            ⚠️ {paymentError}
          </p>
        )}
        <button
          onClick={handlePayment}
          disabled={
            !selectedMethod || paymentMutation.isPending || awaitingAmount
          }
          className="btn-primary w-full py-3 font-semibold disabled:opacity-50 disabled:cursor-not-allowed"
        >
          {paymentMutation.isPending ? (
            <span className="flex items-center justify-center gap-2">
              <Loader2 className="w-4 h-4 animate-spin" /> Processing...
            </span>
          ) : awaitingAmount ? (
            <span className="flex items-center justify-center gap-2">
              <Loader2 className="w-4 h-4 animate-spin" /> Calculating amount...
            </span>
          ) : (
            `Pay ${confirmedCurrency} ${(totalAmountDisplay ?? 0).toFixed(2)}`
          )}
        </button>
        <button
          onClick={() => router.push("/booking/lookup")}
          disabled={paymentMutation.isPending}
          className="btn-secondary w-full flex items-center justify-center gap-2"
        >
          <ChevronLeft className="w-4 h-4" />
          Back
        </button>
        <p className="text-xs text-gray-500 dark:text-gray-400 text-center pt-1">
          🔒 Secure & encrypted payment
        </p>
      </div>
    </div>
  );

  if (isPendingPayment && !isExpired) {
    return (
      <div className="min-h-screen bg-gray-50 dark:bg-gray-900 py-6 pb-6 lg:pb-10">
        <div className="container mx-auto px-4">
          <div className="max-w-6xl mx-auto">
            <h1 className="text-2xl font-bold mb-4 text-gray-900 dark:text-gray-100">
              Complete payment
            </h1>

            <div className="card mb-4 flex items-start justify-between gap-3">
              <div>
                <p className="text-sm text-gray-500 dark:text-gray-400">
                  Booking Reference:{" "}
                  <span className="font-mono font-semibold text-gray-900 dark:text-gray-100">
                    {booking.bookingRef}
                  </span>
                </p>
                {booking.createdAt && (
                  <p className="text-xs text-gray-500 dark:text-gray-400 mt-1 flex items-center gap-1.5">
                    <Clock className="w-3.5 h-3.5" />
                    Booking created on{" "}
                    {format(new Date(booking.createdAt), "PPpp")}
                  </p>
                )}
              </div>
              <StatusBadge />
            </div>

            {/* Two-column grid — matches /booking/payment's layout */}
            <div className="lg:grid lg:grid-cols-3 lg:gap-6 lg:items-start">
              {/* Left column — trip/payment method (2/3 width) */}
              <div className="lg:col-span-2 space-y-4">
                <div className="card">
                  <h2 className="text-lg font-bold text-gray-900 dark:text-white mb-4">
                    Trip Summary
                  </h2>

                  {renderJourneyLegs()}

                  <div className="border-t border-gray-200 dark:border-gray-700 pt-4">
                    <div className="flex items-center gap-2 mb-3">
                      <Users className="w-4 h-4 text-gray-500" />
                      <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">
                        {groupedPassengers.length} Passenger(s)
                      </span>
                    </div>
                    <div className="space-y-2">
                      {groupedPassengers.map((passenger: any, idx: number) => (
                        <div
                          key={idx}
                          className="text-sm py-2 px-3 bg-gray-50 dark:bg-gray-900 rounded-lg"
                        >
                          <div className="flex items-center justify-between">
                            <div className="text-gray-900 dark:text-white font-medium">
                              {passenger.fullName}
                            </div>
                            <div className="text-xs text-gray-500 dark:text-gray-400">
                              {passenger.category}
                            </div>
                          </div>
                          {isRoundTripBooking ? (
                            <div className="mt-1.5 grid grid-cols-2 gap-2">
                              {(
                                [
                                  { legLabel: "Outbound", seat: passenger.outboundSeat },
                                  { legLabel: "Return", seat: passenger.returnSeat },
                                ] as const
                              ).map(({ legLabel, seat }) => (
                                <div key={legLabel}>
                                  <div className="text-xs text-gray-400 dark:text-gray-500">
                                    {legLabel}
                                  </div>
                                  <div className="font-semibold text-gray-900 dark:text-white">
                                    Seat {seat?.number ?? "--"}
                                  </div>
                                  <div className="text-xs text-gray-500 dark:text-gray-400">
                                    {seat?.seatClass}
                                  </div>
                                </div>
                              ))}
                            </div>
                          ) : (
                            <div className="mt-1.5 text-right">
                              <div className="font-semibold text-gray-900 dark:text-white">
                                Seat {passenger.outboundSeat?.number}
                              </div>
                              <div className="text-xs text-gray-500 dark:text-gray-400">
                                {passenger.outboundSeat?.seatClass}
                              </div>
                            </div>
                          )}
                        </div>
                      ))}
                    </div>
                  </div>
                </div>

                <div className="card">
                  <h2 className="text-lg font-bold text-gray-900 dark:text-white mb-4">
                    Select payment method
                  </h2>

                  {paymentMethods &&
                  Array.isArray(paymentMethods) &&
                  paymentMethods.length > 0 ? (
                    <div className="space-y-3">
                      {paymentMethods.map((method: any) => {
                        const Icon = getIconForMethod(method.type);
                        const isSelected = selectedMethod === method.type;
                        return (
                          <button
                            key={method.id}
                            onClick={() => {
                              setSelectedMethod(method.type);
                              setSelectedMethodCurrency(
                                method.currency ?? null,
                              );
                              // Mobile only — desktop's Pay button lives inline in the
                              // sidebar OrderSummary, not behind a modal.
                              if (window.innerWidth < 1024) {
                                setPaymentModalOpen(true);
                              }
                            }}
                            disabled={
                              paymentMutation.isPending ||
                              method.enabled === false
                            }
                            className={`w-full p-4 rounded-xl border-2 transition-all text-left ${
                              isSelected
                                ? "border-primary bg-primary/8 dark:bg-primary/15 shadow-md"
                                : "border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 hover:border-primary/50"
                            } ${paymentMutation.isPending || method.enabled === false ? "opacity-50 cursor-not-allowed" : ""}`}
                          >
                            <div className="flex items-center gap-3">
                              <div
                                className={`w-11 h-11 rounded-lg flex items-center justify-center flex-shrink-0 ${isSelected ? "bg-primary" : "bg-gray-100 dark:bg-gray-700"}`}
                              >
                                <Icon
                                  className={`w-5 h-5 ${isSelected ? "text-white" : "text-primary"}`}
                                />
                              </div>
                              <div className="flex-1 min-w-0">
                                <p className="font-semibold text-gray-900 dark:text-gray-100">
                                  {method.displayName}
                                </p>
                                <p className="text-xs text-gray-500 dark:text-gray-400">
                                  {method.region} · {method.currency}
                                </p>
                              </div>
                              {isSelected && (
                                <CheckCircle2 className="w-5 h-5 text-primary flex-shrink-0" />
                              )}
                            </div>
                          </button>
                        );
                      })}
                    </div>
                  ) : (
                    <div className="text-center py-8 text-gray-500 dark:text-gray-400">
                      No payment methods available
                    </div>
                  )}
                </div>

                {/* Order summary inline — mobile only */}
                <div className="lg:hidden">
                  <OrderSummary />
                </div>
              </div>

              {/* Right column — sticky order summary (desktop only) */}
              <div className="hidden lg:block">
                <div className="sticky top-6">
                  <OrderSummary />
                </div>
              </div>
            </div>
            {/* end grid */}
          </div>
        </div>

        {/* Mobile payment dialog — the amount + Back/Pay buttons live here now,
            opened by picking a payment method above. Centered dialog-box style
            (not a full-screen sheet) so it can't end up pinned under system chrome. */}
        {paymentModalOpen && (
          <div
            className="lg:hidden fixed inset-0 z-[100] flex items-center justify-center p-4"
            role="dialog"
            aria-modal="true"
            aria-labelledby="payment-modal-title"
          >
            {/* Backdrop */}
            <div
              className="absolute inset-0 bg-black/50 backdrop-blur-sm"
              onClick={() => setPaymentModalOpen(false)}
            />

            {/* Dialog */}
            <div className="relative bg-white dark:bg-gray-800 rounded-2xl shadow-2xl max-w-sm w-full animate-in zoom-in-95 duration-200">
              <div className="flex items-center justify-between px-5 pt-5">
                <h2
                  id="payment-modal-title"
                  className="text-base font-bold text-gray-900 dark:text-gray-100"
                >
                  Confirm payment
                </h2>
                <button
                  type="button"
                  onClick={() => setPaymentModalOpen(false)}
                  aria-label="Close"
                  className="p-1.5 -mr-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
                >
                  <X className="w-5 h-5" />
                </button>
              </div>

              <div className="px-5 pt-3 pb-1">
                <div className="flex items-center justify-between mb-2">
                  <span className="text-sm text-gray-600 dark:text-gray-400">
                    Total
                  </span>
                  <span className="text-xl font-bold text-primary flex items-center gap-1.5">
                    {awaitingAmount ? (
                      <Loader2 className="w-4 h-4 animate-spin" />
                    ) : (
                      <>
                        {confirmedCurrency}{" "}
                        {(totalAmountDisplay ?? 0).toFixed(2)}
                      </>
                    )}
                  </span>
                </div>
                <p className="text-xs text-gray-500 dark:text-gray-400">
                  {selectedPaymentMethod
                    ? `via ${selectedPaymentMethod.displayName}`
                    : "Select a payment method to continue."}
                </p>
                {paymentError && (
                  <p className="text-red-600 dark:text-red-400 text-xs mt-2">
                    ⚠️ {paymentError}
                  </p>
                )}
              </div>

              <div className="px-5 pt-3 pb-5">
                <button
                  onClick={handlePayment}
                  disabled={
                    !selectedMethod || paymentMutation.isPending || awaitingAmount
                  }
                  className="btn-primary w-full py-2.5 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  {paymentMutation.isPending ? (
                    <span className="flex items-center justify-center gap-1.5">
                      <Loader2 className="w-4 h-4 animate-spin" /> Processing...
                    </span>
                  ) : awaitingAmount ? (
                    <span className="flex items-center justify-center gap-1.5">
                      <Loader2 className="w-4 h-4 animate-spin" /> Calculating...
                    </span>
                  ) : (
                    `Pay ${confirmedCurrency} ${(totalAmountDisplay ?? 0).toFixed(2)}`
                  )}
                </button>
              </div>
            </div>
          </div>
        )}
      </div>
    );
  }

  if (isConfirmed || isCancelled || isExpired) {
    return (
      <div className="min-h-screen bg-gray-50 dark:bg-gray-900 py-6">
        <div className="container mx-auto px-4">
          <div className="max-w-4xl mx-auto">
            <div className="bg-white dark:bg-gray-800 rounded-2xl p-8 mb-6 text-center border border-gray-200 dark:border-gray-700">
              <div
                className={`w-20 h-20 ${isConfirmed ? "bg-green-100 dark:bg-green-900/30" : "bg-gray-100 dark:bg-gray-700"} rounded-full flex items-center justify-center mx-auto mb-4`}
              >
                {isConfirmed ? (
                  <CheckCircle2 className="w-10 h-10 text-green-600 dark:text-green-400" />
                ) : (
                  <AlertCircle className="w-10 h-10 text-gray-500" />
                )}
              </div>
              <h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-2">
                {isConfirmed
                  ? "Booking Confirmed!"
                  : isCancelled
                    ? "Booking Cancelled"
                    : "Booking Expired"}
              </h1>
              <p className="text-gray-600 dark:text-gray-400 mb-6">
                {isConfirmed
                  ? "Your tickets have been generated successfully"
                  : isCancelled
                    ? "This booking has been cancelled"
                    : "This booking has expired"}
              </p>

              <div className="inline-flex items-center gap-3 bg-gray-50 dark:bg-gray-900 rounded-xl px-6 py-4">
                <div className="text-left">
                  <div className="text-xs text-gray-500 dark:text-gray-400 mb-1">
                    Booking Reference
                  </div>
                  <div className="text-2xl font-mono font-bold text-primary">
                    {booking.bookingRef}
                  </div>
                </div>
                <button
                  onClick={copyPNR}
                  className="w-10 h-10 rounded-lg bg-white dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 border border-gray-200 dark:border-gray-700 flex items-center justify-center transition-all"
                >
                  {copiedPNR ? (
                    <Check className="w-5 h-5 text-green-600" />
                  ) : (
                    <Copy className="w-5 h-5 text-gray-600 dark:text-gray-400" />
                  )}
                </button>
              </div>


              <div className="flex flex-wrap gap-3 justify-center mt-6">
                {isConfirmed && (
                  <>
                    <button
                      onClick={handleDownloadVoucher}
                      disabled={isGeneratingVoucher}
                      className="btn-primary flex items-center gap-2"
                    >
                      {isGeneratingVoucher ? (
                        <>
                          <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
                          Generating...
                        </>
                      ) : (
                        <>
                          <Download className="w-4 h-4" />
                          Download Voucher
                        </>
                      )}
                    </button>
                  </>
                )}
              </div>
            </div>

            <div className="bg-white dark:bg-gray-800 rounded-2xl p-6 mb-6 border border-gray-200 dark:border-gray-700">
              <h2 className="text-lg font-bold text-gray-900 dark:text-white mb-4">
                Journey Details
              </h2>

              {renderJourneyLegs()}
            </div>

            <div className="bg-white dark:bg-gray-800 rounded-2xl p-6 border border-gray-200 dark:border-gray-700">
              <h2 className="text-lg font-bold text-gray-900 dark:text-white mb-4">
                Passenger Details ({groupedPassengers.length})
              </h2>

              <div className="space-y-4">
                {groupedPassengers.map((passenger: any, idx: number) => (
                  <div
                    key={idx}
                    className="border border-gray-200 dark:border-gray-700 rounded-xl p-4 space-y-4"
                  >
                    <div className="flex items-center gap-2">
                      <span className="w-6 h-6 bg-primary text-white rounded-full flex items-center justify-center text-xs font-bold">
                        {idx + 1}
                      </span>
                      <h3 className="font-bold text-gray-900 dark:text-white">
                        {passenger.fullName}
                      </h3>
                      <span className="text-xs px-2 py-1 bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400 rounded-full">
                        {passenger.category}
                      </span>
                    </div>

                    {isRoundTripBooking ? (
                      <div className="grid gap-4 md:grid-cols-2">
                        {(
                          [
                            { legLabel: "Outbound", seat: passenger.outboundSeat },
                            { legLabel: "Return", seat: passenger.returnSeat },
                          ] as const
                        ).map(({ legLabel, seat }) => (
                          <div
                            key={legLabel}
                            className="flex items-center gap-4 pt-3 border-t border-gray-100 dark:border-gray-800 first:border-t-0 first:pt-0 md:border-t-0 md:pt-0"
                          >
                            <div className="flex-1">
                              <span className="inline-block mb-2 text-xs font-semibold px-2 py-0.5 rounded-full bg-primary/10 text-primary">
                                {legLabel}
                              </span>
                              <SeatDetailsGrid seat={seat} />
                            </div>
                          </div>
                        ))}
                      </div>
                    ) : (
                      <div className="flex flex-col md:flex-row md:items-center gap-4">
                        <div className="flex-1">
                          <SeatDetailsGrid seat={passenger.outboundSeat} />
                        </div>
                      </div>
                    )}
                  </div>
                ))}
              </div>
            </div>

            <div className="mt-6 text-center">
              <button
                onClick={() => router.push("/booking/search")}
                className="btn-primary"
              >
                Book Another Trip
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  // Fallback for any other status
  return (
    <div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center p-4">
      <div className="bg-white dark:bg-gray-800 rounded-2xl p-8 text-center max-w-md w-full">
        <div className="w-16 h-16 bg-gray-100 dark:bg-gray-700 rounded-full flex items-center justify-center mx-auto mb-4">
          <AlertCircle className="w-8 h-8 text-gray-500" />
        </div>
        <h2 className="text-xl font-bold text-gray-900 dark:text-white mb-2">
          Unknown Booking Status
        </h2>
        <p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
          Booking status: {booking.status}
        </p>
        <button
          onClick={() => router.push("/booking/search")}
          className="btn-primary"
        >
          New Booking
        </button>
      </div>
    </div>
  );
}

export default function BookingDetailPage() {
  return (
    <Suspense
      fallback={
        <div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center p-4">
          <div className="bg-white dark:bg-gray-800 rounded-2xl p-8 text-center max-w-md w-full">
            <div className="w-16 h-16 border-4 border-primary border-t-transparent rounded-full animate-spin mx-auto mb-4" />
            <h2 className="text-xl font-bold text-gray-900 dark:text-white mb-2">
              Loading...
            </h2>
          </div>
        </div>
      }
    >
      <BookingDetailContent />
    </Suspense>
  );
}
