import { useEffect, useMemo, useRef, useState } from "react";

import {
  createBooking,
  fetchPublicSettings,
  fetchRoutes,
  fetchTrips,
  mapApiTrip,
} from "@/api/client";
import {
  BOOKING_WIZARD_STEPS,
  DEFAULT_BOOKING_SEARCH,
  getRouteSelectOptions,
  DEFAULT_NATIONALITY,
  NATIONALITY_OPTIONS,
  parseRouteSelection,
  resolveTripRouteSlugs,
  routesToBookingOptions,
  SEAT_CLASS_OPTIONS,
  type ApiRoute,
  type BookingTripType,
  type MockTrip,
  type SeatClass,
} from "@/config/booking-config";
import type { PublicPaymentSettings } from "@/config/booking-payment";
import { BookingPaymentPanel } from "@/components/booking/BookingPaymentPanel";
import { SITE } from "@/config/navigation";
import type { BookerInfo, PassengerInfo } from "@/components/booking/booking-types";
import { BookingBirthDateControl } from "@/components/booking/BookingBirthDateControl";
import { BookingTripDateControl } from "@/components/booking/BookingTripDateControl";
import { BookingFieldError, fieldInvalidClass } from "@/components/booking/BookingFieldError";
import { BookingIcon } from "@/components/booking/BookingIcons";
import { BookingNationalitySelect } from "@/components/booking/BookingNationalitySelect";
import { BookingRouteSelect } from "@/components/booking/BookingRouteSelect";
import { BookingSearchControl } from "@/components/booking/BookingSearchControl";
import {
  clearFieldError,
  validateBookerStep,
  validatePassengersStep,
  type FieldErrors,
} from "@/lib/booking-form-validation";
import {
  compareIsoDates,
  defaultDepartDateDisplay,
  defaultReturnDateDisplay,
  displayDateToIso,
  filterTripsForPassengers,
  formatVnd,
  isoDateToDisplay,
  todayIsoDate,
} from "@/lib/booking-search";

const EMPTY_BOOKER: BookerInfo = {
  fullName: "",
  phone: "",
  email: "",
  note: "",
};

function emptyPassenger(): PassengerInfo {
  return {
    fullName: "",
    birthDate: "",
    nationality: DEFAULT_NATIONALITY,
    idNumber: "",
    hometown: "",
  };
}

/** Cuộn viewport tới đầu block đặt vé (sau khi chuyển màn hình thành công). */
function scrollBookingWidgetToTop(root: HTMLElement): void {
  const anchor = root.closest<HTMLElement>(".ferry-booking-mount") ?? root;
  const adminBar = document.getElementById("wpadminbar");
  const offset = adminBar ? adminBar.offsetHeight + 12 : 12;
  const top = anchor.getBoundingClientRect().top + window.scrollY - offset;
  window.scrollTo({ top: Math.max(0, top), behavior: "smooth" });
}

function TripTable({
  trips,
  selectedId,
  onSelect,
  defaultOperatorLogo,
}: {
  trips: MockTrip[];
  selectedId: string | null;
  onSelect: (trip: MockTrip) => void;
  defaultOperatorLogo?: string;
}) {
  if (trips.length === 0) {
    return <div className="ferry-booking__empty">Không có chuyến phù hợp ngày đã chọn.</div>;
  }

  return (
    <div className="ferry-booking__table-wrap">
      <table className="ferry-booking__table">
        <colgroup>
          <col className="ferry-booking__col-route" />
          <col className="ferry-booking__col-operator" />
          <col className="ferry-booking__col-time" />
          <col className="ferry-booking__col-time" />
          <col className="ferry-booking__col-price" />
          <col className="ferry-booking__col-pick" />
        </colgroup>
        <thead>
          <tr>
            <th className="ferry-booking__th-route">Tuyến</th>
            <th>Hãng tàu</th>
            <th>Giờ đi</th>
            <th>Giờ đến</th>
            <th>Giá vé</th>
            <th>Chọn</th>
          </tr>
        </thead>
        <tbody>
          {trips.map((trip) => {
            const isSelected = selectedId === trip.id;
            const canSelect = trip.availability === "available";
            return (
              <tr key={trip.id} className={isSelected ? "is-selected" : undefined}>
                <td className="ferry-booking__cell-route">{trip.routeLabel}</td>
                <td className="ferry-booking__cell-operator">
                  <div className="ferry-booking__operator">
                    <img
                      alt=""
                      className="ferry-booking__operator-logo"
                      src={trip.operatorLogo || defaultOperatorLogo || ""}
                    />
                    <span>{trip.operator}</span>
                  </div>
                </td>
                <td className="ferry-booking__time">{trip.departure}</td>
                <td className="ferry-booking__time">{trip.arrival}</td>
                <td className="ferry-booking__price">{formatVnd(trip.priceVnd)}</td>
                <td className="ferry-booking__cell-pick">
                  {canSelect ? (
                    <button
                      className={`ferry-booking__pick ${
                        isSelected ? "ferry-booking__pick--selected" : "ferry-booking__pick--available"
                      }`}
                      type="button"
                      onClick={() => onSelect(trip)}
                    >
                      {isSelected ? "Đã chọn" : "Chọn"}
                    </button>
                  ) : (
                    <span className="ferry-booking__pick ferry-booking__pick--sold">Hết vé</span>
                  )}
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

type WizardProps = {
  initialRouteSlug?: string;
};

export function FerryBookingWizard({ initialRouteSlug = "" }: WizardProps) {
  const [step, setStep] = useState(1);
  const [tripType, setTripType] = useState<BookingTripType>(DEFAULT_BOOKING_SEARCH.tripType);
  const [seatClass, setSeatClass] = useState<SeatClass>(DEFAULT_BOOKING_SEARCH.seatClass);
  const [routeId, setRouteId] = useState(
    initialRouteSlug || DEFAULT_BOOKING_SEARCH.routeId,
  );
  const [passengers, setPassengers] = useState(DEFAULT_BOOKING_SEARCH.passengers);
  const [departDate, setDepartDate] = useState(defaultDepartDateDisplay);
  const [returnDate, setReturnDate] = useState(defaultReturnDateDisplay);
  const [hasSearched, setHasSearched] = useState(false);
  const [searchLoading, setSearchLoading] = useState(false);
  const [searchError, setSearchError] = useState<string | null>(null);
  const [outboundTrips, setOutboundTrips] = useState<MockTrip[]>([]);
  const [inboundTrips, setInboundTrips] = useState<MockTrip[]>([]);
  const [selectedOutboundId, setSelectedOutboundId] = useState<string | null>(null);
  const [selectedReturnId, setSelectedReturnId] = useState<string | null>(null);
  const [booker, setBooker] = useState<BookerInfo>(EMPTY_BOOKER);
  const [passengerForms, setPassengerForms] = useState<PassengerInfo[]>([emptyPassenger()]);
  const [submitted, setSubmitted] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [bookingCode, setBookingCode] = useState<string | null>(null);
  const [fieldErrors, setFieldErrors] = useState<FieldErrors>({});
  const [apiRoutes, setApiRoutes] = useState<ApiRoute[]>([]);
  const [bootstrapError, setBootstrapError] = useState<string | null>(null);
  const [paymentSettings, setPaymentSettings] = useState<PublicPaymentSettings | null>(null);
  const rootRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!submitted) return;
    const root = rootRef.current;
    if (!root) return;
    const id = window.requestAnimationFrame(() => {
      scrollBookingWidgetToTop(root);
    });
    return () => window.cancelAnimationFrame(id);
  }, [submitted]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const [routes, settings] = await Promise.all([fetchRoutes(), fetchPublicSettings()]);
        if (cancelled) return;
        setApiRoutes(routes);
        setPaymentSettings(settings);
        if (initialRouteSlug && routes.some((r) => r.slug === initialRouteSlug)) {
          setRouteId(initialRouteSlug);
        } else if (routes.length && !routes.some((r) => r.slug === routeId)) {
          setRouteId(routes[0].slug);
        }
      } catch {
        if (!cancelled) {
          setBootstrapError("Không tải được dữ liệu đặt vé. Vui lòng tải lại trang.");
        }
      }
    })();
    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps -- chỉ bootstrap một lần
  }, [initialRouteSlug]);

  const routeOptions = useMemo(() => routesToBookingOptions(apiRoutes), [apiRoutes]);
  const selectedOutbound = outboundTrips.find((t) => t.id === selectedOutboundId) ?? null;
  const selectedReturn = inboundTrips.find((t) => t.id === selectedReturnId) ?? null;

  const routeSelectOptions = useMemo(
    () => getRouteSelectOptions(tripType, routeOptions),
    [tripType, routeOptions],
  );
  const routeOption = routeSelectOptions.find((r) => r.id === routeId);
  const baseRouteId = parseRouteSelection(routeId).baseRouteId;

  const todayIso = todayIsoDate();
  const departIso = displayDateToIso(departDate);
  const minReturnIso = useMemo(() => {
    if (departIso && compareIsoDates(departIso, todayIso) > 0) return departIso;
    return todayIso;
  }, [departIso, todayIso]);

  const calendarRouteSlugs = useMemo(
    () => resolveTripRouteSlugs(apiRoutes, routeId, tripType),
    [apiRoutes, routeId, tripType],
  );

  useEffect(() => {
    if (departIso && compareIsoDates(departIso, todayIso) < 0) {
      setDepartDate(isoDateToDisplay(todayIso) || defaultDepartDateDisplay());
    }
    const retIso = displayDateToIso(returnDate);
    if (retIso && compareIsoDates(retIso, minReturnIso) < 0) {
      setReturnDate(isoDateToDisplay(minReturnIso) || defaultReturnDateDisplay());
    }
  }, [departIso, minReturnIso, returnDate, todayIso]);

  function selectTripType(next: BookingTripType) {
    setTripType(next);
    if (routeId.endsWith("-rev")) {
      setRouteId(parseRouteSelection(routeId).baseRouteId);
    }
    setHasSearched(false);
    setSelectedOutboundId(null);
    setSelectedReturnId(null);
  }

  async function runSearch() {
    setSearchError(null);
    setSearchLoading(true);
    setSelectedOutboundId(null);
    setSelectedReturnId(null);
    setFieldErrors({});
    try {
      // Luôn lấy tuyến mới (reverse_route) — tránh cache React sau khi admin sửa Tuyến.
      const routesFresh = await fetchRoutes();
      setApiRoutes(routesFresh);
      const { outboundSlug, inboundSlug } = resolveTripRouteSlugs(routesFresh, routeId, tripType);
      if (!outboundSlug) {
        setSearchError("Chưa cấu hình tuyến tàu.");
        setHasSearched(false);
        return;
      }
      if (tripType === "round-trip" && !inboundSlug) {
        setSearchError("Tuyến này chưa có chiều về (reverse route).");
        setHasSearched(false);
        return;
      }
      const outboundRaw = await fetchTrips(outboundSlug, departDate, seatClass);
      const inboundRaw =
        tripType === "round-trip" && inboundSlug
          ? await fetchTrips(inboundSlug, returnDate, seatClass)
          : [];
      setOutboundTrips(
        filterTripsForPassengers(
          outboundRaw.map((t) => mapApiTrip(t, "a-to-b")),
          passengers,
        ),
      );
      setInboundTrips(
        filterTripsForPassengers(
          inboundRaw.map((t) => mapApiTrip(t, "b-to-a")),
          passengers,
        ),
      );
      setHasSearched(true);
    } catch {
      setSearchError("Không tìm được chuyến. Vui lòng thử lại.");
      setHasSearched(false);
    } finally {
      setSearchLoading(false);
    }
  }

  function syncPassengerForms(count: number) {
    setPassengerForms((prev) => {
      const next = [...prev];
      while (next.length < count) next.push(emptyPassenger());
      return next.slice(0, count);
    });
  }

  function handlePassengersChange(count: number) {
    const safe = Math.min(9, Math.max(1, count));
    setPassengers(safe);
    syncPassengerForms(safe);
  }

  function addPassengerForm() {
    setPassengerForms((prev) => {
      if (prev.length >= 9) return prev;
      const next = [...prev, emptyPassenger()];
      setPassengers(next.length);
      return next;
    });
    setFieldErrors({});
  }

  function removePassengerForm(index: number) {
    setPassengerForms((prev) => {
      if (prev.length <= 1) return prev;
      const next = prev.filter((_, i) => i !== index);
      setPassengers(next.length);
      return next;
    });
    setFieldErrors({});
  }

  function canProceedFromStep1(): boolean {
    if (!selectedOutbound) return false;
    if (tripType === "round-trip" && !selectedReturn) return false;
    return true;
  }

  const showContinueButton = step !== 1 || canProceedFromStep1();

  async function goNext() {
    if (step === 2) {
      const errors = validateBookerStep(booker);
      if (Object.keys(errors).length > 0) {
        setFieldErrors(errors);
        return;
      }
    }
    if (step === 3) {
      const errors = validatePassengersStep(passengerForms, { tripDepartDate: departDate });
      if (Object.keys(errors).length > 0) {
        setFieldErrors(errors);
        return;
      }
    }
    setFieldErrors({});
    if (step === 4) {
      if (!selectedOutbound) return;
      setSubmitting(true);
      try {
        const result = await createBooking({
          tripType,
          seatClass,
          outboundTripId: Number(selectedOutbound.id),
          inboundTripId:
            tripType === "round-trip" && selectedReturn ? Number(selectedReturn.id) : undefined,
          booker,
          passengers: passengerForms,
        });
        setBookingCode(result.bookingCode);
        setSubmitted(true);
      } catch (err) {
        const msg = err instanceof Error ? err.message : "Không thể tạo đơn.";
        setFieldErrors({ submit: msg });
      } finally {
        setSubmitting(false);
      }
      return;
    }
    if (step === 1 || step === 2) syncPassengerForms(passengers);
    if (step === 3) setPassengers(passengerForms.length);
    setStep((s) => Math.min(4, s + 1));
  }

  function goBack() {
    setFieldErrors({});
    setStep((s) => Math.max(1, s - 1));
  }

  function startNewBooking() {
    setSubmitted(false);
    setBookingCode(null);
    setStep(1);
    setFieldErrors({});
    setSelectedOutboundId(null);
    setSelectedReturnId(null);
    setBooker(EMPTY_BOOKER);
    setPassengers(DEFAULT_BOOKING_SEARCH.passengers);
    setPassengerForms(
      Array.from({ length: DEFAULT_BOOKING_SEARCH.passengers }, () => emptyPassenger()),
    );
    setSeatClass(DEFAULT_BOOKING_SEARCH.seatClass);
    setDepartDate(defaultDepartDateDisplay());
    setReturnDate(defaultReturnDateDisplay());
  }

  const stepperUi = (
    <div className="ferry-booking__stepper" aria-label="Tiến trình đặt vé">
      <div className="ferry-booking__stepper-rail">
        <div className="ferry-booking__stepper-line" aria-hidden />
        {BOOKING_WIZARD_STEPS.map((s) => {
          const isCompleteFlow = submitted;
          const isDone = isCompleteFlow || step > s.id;
          const isActive = isCompleteFlow ? s.id === 4 : step === s.id;
          return (
            <div
              key={s.id}
              className={`ferry-booking__step-item${isActive ? " is-active" : ""}${isDone ? " is-done" : ""}`}
            >
              <span className="ferry-booking__step-label">{s.label}</span>
              <span className="ferry-booking__step-dot" aria-hidden />
            </div>
          );
        })}
      </div>
    </div>
  );

  if (bootstrapError) {
    return <div className="ferry-booking ferry-booking__empty">{bootstrapError}</div>;
  }

  if (!paymentSettings) {
    return <div className="ferry-booking ferry-booking__empty">Đang tải form đặt vé…</div>;
  }

  const operatorLogoFallback = paymentSettings.defaultOperatorLogo;

  if (submitted) {
    return (
      <div ref={rootRef} className="ferry-booking">
        {stepperUi}
        <div className="ferry-booking__panel ferry-booking__success">
          <header className="ferry-booking__success-hero">
            <div className="ferry-booking__success-icon" aria-hidden>
              ✓
            </div>
            <h3 className="ferry-booking__success-title">Đã ghi nhận yêu cầu đặt vé</h3>
            <p className="ferry-booking__success-lead">
              Yêu cầu đã được ghi nhận. Phòng vé sẽ xác nhận sau khi nhận thanh toán.
              {bookingCode ? (
                <>
                  {" "}
                  Mã đơn: <strong>{bookingCode}</strong>
                </>
              ) : null}
            </p>
          </header>
          <div className="ferry-booking__success-body">
            <BookingPaymentPanel
              booker={booker}
              inbound={selectedReturn}
              outbound={selectedOutbound}
              passengers={passengerForms}
              paymentSettings={paymentSettings}
              routeLabel={routeOption?.label ?? baseRouteId}
              seatClass={seatClass}
              surface="success"
              tripType={tripType}
            />
          </div>
          <footer className="ferry-booking__success-footer">
            <p className="ferry-booking__success-note">
              Hotline hỗ trợ: {SITE.hotlinePrimary} — {SITE.email}
            </p>
            <div className="ferry-booking__success-actions">
              <button className="ferry-booking__search-btn" type="button" onClick={startNewBooking}>
                Đặt vé mới
              </button>
            </div>
          </footer>
        </div>
      </div>
    );
  }

  return (
    <div ref={rootRef} className="ferry-booking">
      {stepperUi}

      <div className="ferry-booking__panel">
        {step === 1 ? (
          <>
            <div className="ferry-booking__search-card">
              <div className="ferry-booking__search-card-intro">
                <h2 className="ferry-booking__search-card-title">Tìm chuyến tàu của bạn</h2>
                <p className="ferry-booking__search-card-sub">Kết nối hành trình, khám phá muôn nơi</p>
              </div>
              <div
                className="ferry-booking__trip-toggle ferry-booking__trip-toggle--card"
                role="group"
                aria-label="Loại vé"
              >
                <button
                  aria-pressed={tripType === "one-way"}
                  className={tripType === "one-way" ? "is-active" : ""}
                  type="button"
                  onClick={() => selectTripType("one-way")}
                >
                  Một chiều
                </button>
                <button
                  aria-pressed={tripType === "round-trip"}
                  className={tripType === "round-trip" ? "is-active" : ""}
                  type="button"
                  onClick={() => selectTripType("round-trip")}
                >
                  Khứ hồi
                </button>
              </div>
              <div
                className={`ferry-booking__search-row${tripType === "round-trip" ? " ferry-booking__search-row--roundtrip" : " ferry-booking__search-row--oneway"}`}
              >
                <div className="ferry-booking__search-field ferry-booking__search-field--route">
                  <span className="ferry-booking__field-label">Chuyến</span>
                  <BookingRouteSelect
                    options={routeSelectOptions}
                    value={routeId}
                    onChange={(id) => {
                      setRouteId(id);
                      setHasSearched(false);
                      setSelectedOutboundId(null);
                      setSelectedReturnId(null);
                    }}
                  />
                </div>
                <div className="ferry-booking__search-field">
                  <label className="ferry-booking__field-label" htmlFor="ferry-passenger-count">
                    Hành khách
                  </label>
                  <BookingSearchControl icon="user">
                    <input
                      id="ferry-passenger-count"
                      className="ferry-booking__control-input"
                      max={9}
                      min={1}
                      type="number"
                      value={passengers}
                      onChange={(e) => handlePassengersChange(Number(e.target.value))}
                    />
                  </BookingSearchControl>
                </div>
                <div className="ferry-booking__search-field">
                  <span className="ferry-booking__field-label">Ngày đi</span>
                  <BookingTripDateControl
                    aria-label="Ngày đi"
                    minIso={todayIso}
                    routeSlug={calendarRouteSlugs.outboundSlug}
                    seatClass={seatClass}
                    valueIso={departIso || todayIso}
                    onChangeDisplay={(next) => {
                      setDepartDate(next);
                      const nextIso = displayDateToIso(next);
                      const retIso = displayDateToIso(returnDate);
                      if (nextIso && retIso && compareIsoDates(retIso, nextIso) < 0) {
                        setReturnDate(next);
                      }
                      setHasSearched(false);
                      setSelectedOutboundId(null);
                      setSelectedReturnId(null);
                    }}
                  />
                </div>
                {tripType === "round-trip" ? (
                  <div className="ferry-booking__search-field">
                    <span className="ferry-booking__field-label">Ngày về</span>
                    <BookingTripDateControl
                      aria-label="Ngày về"
                      minIso={minReturnIso}
                      routeSlug={calendarRouteSlugs.inboundSlug}
                      seatClass={seatClass}
                      valueIso={displayDateToIso(returnDate) || minReturnIso}
                      onChangeDisplay={(next) => {
                        setReturnDate(next);
                        setHasSearched(false);
                        setSelectedOutboundId(null);
                        setSelectedReturnId(null);
                      }}
                    />
                  </div>
                ) : null}
                <div className="ferry-booking__search-field">
                  <span className="ferry-booking__field-label" id="ferry-seat-class-label">
                    Loại ghế
                  </span>
                  <div
                    aria-labelledby="ferry-seat-class-label"
                    className="ferry-booking__seat-toggle ferry-booking__seat-toggle--field"
                    role="group"
                  >
                    {SEAT_CLASS_OPTIONS.map((option) => (
                      <button
                        key={option.id}
                        className={seatClass === option.id ? "is-active" : ""}
                        type="button"
                        onClick={() => {
                          setSeatClass(option.id);
                          setHasSearched(false);
                          setSelectedOutboundId(null);
                          setSelectedReturnId(null);
                        }}
                      >
                        {option.label}
                      </button>
                    ))}
                  </div>
                </div>
              </div>
              <button
                className="ferry-booking__search-btn ferry-booking__search-btn--full"
                disabled={searchLoading || apiRoutes.length === 0}
                type="button"
                onClick={() => void runSearch()}
              >
                <BookingIcon name="search" /> {searchLoading ? "Đang tìm…" : "Tìm chuyến tàu"}
              </button>
              {searchError ? <p className="ferry-booking__empty">{searchError}</p> : null}
            </div>

            {hasSearched ? (
              <div className="ferry-booking__results">
                <p className="ferry-booking__leg-title">
                  Tuyến {routeOption?.label ?? routeId} ({departDate})
                </p>
                <TripTable
                  defaultOperatorLogo={operatorLogoFallback}
                  selectedId={selectedOutboundId}
                  trips={outboundTrips}
                  onSelect={(trip) => setSelectedOutboundId(trip.id)}
                />
                {tripType === "round-trip" ? (
                  <>
                    <p className="ferry-booking__leg-title">
                      Tuyến {routeOption ? `${routeOption.legB} - ${routeOption.legA}` : ""} ({returnDate})
                    </p>
                    <TripTable
                      defaultOperatorLogo={operatorLogoFallback}
                      selectedId={selectedReturnId}
                      trips={inboundTrips}
                      onSelect={(trip) => setSelectedReturnId(trip.id)}
                    />
                  </>
                ) : null}
              </div>
            ) : null}
          </>
        ) : null}

        {step === 2 ? (
          <>
            <p className="ferry-booking__section-title">LIÊN HỆ</p>
            <div className="ferry-booking__form-grid">
              <div className="ferry-booking__form-field">
                <label htmlFor="booker-name">Tên người đặt vé (*)</label>
                <input
                  id="booker-name"
                  aria-describedby={fieldErrors["booker-name"] ? "booker-name-error" : undefined}
                  aria-invalid={Boolean(fieldErrors["booker-name"])}
                  className={fieldInvalidClass("booker-name", fieldErrors).trim() || undefined}
                  placeholder="Nguyễn Văn A"
                  value={booker.fullName}
                  onChange={(e) => {
                    setBooker({ ...booker, fullName: e.target.value });
                    setFieldErrors((prev) => clearFieldError(prev, "booker-name"));
                  }}
                />
                <BookingFieldError fieldId="booker-name" errors={fieldErrors} />
              </div>
              <div className="ferry-booking__form-field">
                <label htmlFor="booker-phone">Số điện thoại/Zalo (*)</label>
                <input
                  id="booker-phone"
                  aria-describedby={fieldErrors["booker-phone"] ? "booker-phone-error" : undefined}
                  aria-invalid={Boolean(fieldErrors["booker-phone"])}
                  className={fieldInvalidClass("booker-phone", fieldErrors).trim() || undefined}
                  placeholder="09xx xxx xxx"
                  type="tel"
                  value={booker.phone}
                  onChange={(e) => {
                    setBooker({ ...booker, phone: e.target.value });
                    setFieldErrors((prev) => clearFieldError(prev, "booker-phone"));
                  }}
                />
                <BookingFieldError fieldId="booker-phone" errors={fieldErrors} />
              </div>
              <div className="ferry-booking__form-field">
                <label htmlFor="booker-email">Địa chỉ mail</label>
                <input
                  id="booker-email"
                  placeholder="email@example.com"
                  type="email"
                  value={booker.email}
                  onChange={(e) => setBooker({ ...booker, email: e.target.value })}
                />
              </div>
              <div className="ferry-booking__form-field">
                <label htmlFor="booker-note">Ghi chú</label>
                <input
                  id="booker-note"
                  placeholder="Chọn ghế / xuất hóa đơn VAT..."
                  value={booker.note}
                  onChange={(e) => setBooker({ ...booker, note: e.target.value })}
                />
              </div>
            </div>
          </>
        ) : null}

        {step === 3 ? (
          <>
            <div className="ferry-booking__passenger-head">
              <p className="ferry-booking__section-title">HÀNH KHÁCH ({passengerForms.length})</p>
              <button
                className="ferry-booking__add-passenger"
                disabled={passengerForms.length >= 9}
                type="button"
                onClick={addPassengerForm}
              >
                + Thêm hành khách
              </button>
            </div>
            {passengerForms.map((p, index) => (
              <div key={index} className="ferry-booking__passenger-card">
                <div className="ferry-booking__passenger-card-head">
                  <h4>Hành khách {index + 1}</h4>
                  {passengerForms.length > 1 ? (
                    <button
                      className="ferry-booking__remove-passenger"
                      type="button"
                      onClick={() => removePassengerForm(index)}
                    >
                      Xóa
                    </button>
                  ) : null}
                </div>
                <div className="ferry-booking__form-grid">
                  <div className="ferry-booking__form-field">
                    <label htmlFor={`p-name-${index}`}>Họ và tên (*)</label>
                    <input
                      id={`p-name-${index}`}
                      aria-describedby={
                        fieldErrors[`p-name-${index}`] ? `p-name-${index}-error` : undefined
                      }
                      aria-invalid={Boolean(fieldErrors[`p-name-${index}`])}
                      className={fieldInvalidClass(`p-name-${index}`, fieldErrors).trim() || undefined}
                      placeholder="Họ tên in trên vé"
                      value={p.fullName}
                      onChange={(e) => {
                        const next = [...passengerForms];
                        next[index] = { ...p, fullName: e.target.value };
                        setPassengerForms(next);
                        setFieldErrors((prev) => clearFieldError(prev, `p-name-${index}`));
                      }}
                    />
                    <BookingFieldError errors={fieldErrors} fieldId={`p-name-${index}`} />
                  </div>
                  <div className="ferry-booking__form-field">
                    <label htmlFor={`p-birth-${index}`}>Ngày tháng năm sinh (*)</label>
                    <BookingBirthDateControl
                      id={`p-birth-${index}`}
                      invalid={Boolean(fieldErrors[`p-birth-${index}`])}
                      maxDate={departDate}
                      value={p.birthDate}
                      onChange={(birthDate) => {
                        const next = [...passengerForms];
                        next[index] = { ...p, birthDate };
                        setPassengerForms(next);
                        setFieldErrors((prev) => clearFieldError(prev, `p-birth-${index}`));
                      }}
                    />
                    <BookingFieldError errors={fieldErrors} fieldId={`p-birth-${index}`} />
                  </div>
                  <div className="ferry-booking__form-field">
                    <label htmlFor={`p-id-${index}`}>CCCD (*)</label>
                    <input
                      id={`p-id-${index}`}
                      aria-describedby={fieldErrors[`p-id-${index}`] ? `p-id-${index}-error` : undefined}
                      aria-invalid={Boolean(fieldErrors[`p-id-${index}`])}
                      className={fieldInvalidClass(`p-id-${index}`, fieldErrors).trim() || undefined}
                      placeholder="Số CCCD / hộ chiếu"
                      value={p.idNumber}
                      onChange={(e) => {
                        const next = [...passengerForms];
                        next[index] = { ...p, idNumber: e.target.value };
                        setPassengerForms(next);
                        setFieldErrors((prev) => clearFieldError(prev, `p-id-${index}`));
                      }}
                    />
                    <BookingFieldError errors={fieldErrors} fieldId={`p-id-${index}`} />
                  </div>
                  <div className="ferry-booking__form-field">
                    <label htmlFor={`p-nat-${index}`}>Quốc tịch (*)</label>
                    <BookingNationalitySelect
                      inputId={`p-nat-${index}`}
                      invalid={Boolean(fieldErrors[`p-nat-${index}`])}
                      options={NATIONALITY_OPTIONS}
                      value={p.nationality}
                      onChange={(nationality) => {
                        const next = [...passengerForms];
                        next[index] = { ...p, nationality };
                        setPassengerForms(next);
                        setFieldErrors((prev) => clearFieldError(prev, `p-nat-${index}`));
                      }}
                    />
                    <BookingFieldError errors={fieldErrors} fieldId={`p-nat-${index}`} />
                  </div>
                  <div className="ferry-booking__form-field ferry-booking__form-field--full">
                    <label htmlFor={`p-home-${index}`}>Quê quán (*)</label>
                    <input
                      id={`p-home-${index}`}
                      aria-describedby={fieldErrors[`p-home-${index}`] ? `p-home-${index}-error` : undefined}
                      aria-invalid={Boolean(fieldErrors[`p-home-${index}`])}
                      className={fieldInvalidClass(`p-home-${index}`, fieldErrors).trim() || undefined}
                      placeholder="Tỉnh / thành phố"
                      value={p.hometown}
                      onChange={(e) => {
                        const next = [...passengerForms];
                        next[index] = { ...p, hometown: e.target.value };
                        setPassengerForms(next);
                        setFieldErrors((prev) => clearFieldError(prev, `p-home-${index}`));
                      }}
                    />
                    <BookingFieldError errors={fieldErrors} fieldId={`p-home-${index}`} />
                  </div>
                </div>
              </div>
            ))}
            <aside className="ferry-booking__passenger-note" aria-label="Ghi chú hành khách">
              <p className="ferry-booking__passenger-note-line">
                <span className="ferry-booking__passenger-note-mark" aria-hidden>
                  *
                </span>
                Trẻ em dưới 5 tuổi được miễn vé, ngồi cùng bố mẹ (không ghế riêng). Trường hợp Quý khách
                nhập thông tin cho bé vào chúng tôi mặc định hiểu Quý khách muốn có vé riêng cho bé và sẽ
                được tính theo giá vé trẻ em
              </p>
              <p className="ferry-booking__passenger-note-line">
                <span className="ferry-booking__passenger-note-mark ferry-booking__passenger-note-mark--dbl" aria-hidden>
                  **
                </span>
                Các hạng ghế đặc biệt: Người địa phương, Hướng dẫn viên, Người khuyết tật vui lòng liên hệ
                riêng qua hotline:{" "}
                <a className="ferry-booking__passenger-note-hotline" href="tel:0372334697">
                  0372334697
                </a>
              </p>
              <p className="ferry-booking__passenger-note-line">
                <span className="ferry-booking__passenger-note-mark ferry-booking__passenger-note-mark--triple" aria-hidden>
                  ***
                </span>
                Giá vé tuyến Côn Đảo đã bao gồm thu hộ Phí cảng Bến Đầm 18.000đ/khách/lượt
              </p>
            </aside>
          </>
        ) : null}

        {step === 4 ? (
          <>
            <p className="ferry-booking__section-title">THANH TOÁN</p>
            <BookingPaymentPanel
              booker={booker}
              inbound={selectedReturn}
              outbound={selectedOutbound}
              passengers={passengerForms}
              paymentSettings={paymentSettings}
              routeLabel={routeOption?.label ?? baseRouteId}
              seatClass={seatClass}
              tripType={tripType}
            />
            {fieldErrors.submit ? (
              <p className="ferry-booking__empty" role="alert">
                {fieldErrors.submit}
              </p>
            ) : null}
          </>
        ) : null}

        <div className="ferry-booking__nav">
          {step > 1 ? (
            <button className="ferry-booking__nav-back" type="button" onClick={goBack}>
              <BookingIcon className="ferry-booking__icon ferry-booking__icon--nav" name="chevron-double-left" />
              TRỞ LẠI
            </button>
          ) : null}
          {showContinueButton ? (
            <button
              className="ferry-booking__nav-next"
              disabled={submitting}
              type="button"
              onClick={() => void goNext()}
            >
              {step === 4 ? (submitting ? "ĐANG GỬI…" : "XÁC NHẬN ĐẶT VÉ") : "TIẾP TỤC"}
              {step === 4 ? null : (
                <BookingIcon className="ferry-booking__icon ferry-booking__icon--nav" name="chevron-double-right" />
              )}
            </button>
          ) : null}
        </div>
      </div>
    </div>
  );
}
