/* Volaire — /booking part 2: protection slot #1 (Sherpa quote), payment, confirmation, wizard shell */

/* ---------- premium frequency label ---------- */
function freqLabel(frequency, lang) {
  const map = {
    fr: { month: '/mois', year: '/an', quarter: '/trimestre', day: '/jour', 'one-time': '' },
    en: { month: '/mo', year: '/yr', quarter: '/qtr', day: '/day', 'one-time': '' },
    es: { month: '/mes', year: '/año', quarter: '/trimestre', day: '/día', 'one-time': '' },
  };
  return ((map[lang] || map.fr)[frequency]) || '';
}

/* ---------- ProtectionOffer (live Sherpa quote) ---------- */
function ProtectionOffer({ quoteId, plans, value, onSelectionChange }) {
  const { t, lang } = useLang();
  const options = plans.map(function (p) {
    return { id: p.name, title: p.title, premium: p.premium, frequency: p.frequency, currency: p.currency, recommended: p.recommended };
  });
  options.push({ id: 'none', title: t('booking.protection.none'), desc: t('booking.protection.none.desc'), premium: null });
  return (
    <div role="radiogroup" aria-label={t('booking.protection.stepTitle')} className="flex flex-col gap-3">
      <p className="text-sm text-muted">{t('booking.protection.intro')}</p>
      {options.map(function (o) {
        const selected = value === o.id;
        const none = o.id === 'none';
        return (
          <button key={o.id} role="radio" aria-checked={selected}
            onClick={function () {
              onSelectionChange(
                none ? null : { quoteId: quoteId, name: o.id, planName: o.id, coverageType: o.id, title: o.title, premium: o.premium, frequency: o.frequency },
                o.id);
            }}
            className={'relative flex w-full items-start gap-3 rounded-xl p-4 text-left transition-colors ' +
              (selected ? 'border-2 border-cobalt bg-cobalt/5' : 'border border-line bg-white hover:border-muted/40') +
              (none && !selected ? ' opacity-80' : '')}>
            <span className={'mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border-2 ' + (selected ? 'border-cobalt' : 'border-line')}>
              {selected ? <span className="h-2.5 w-2.5 rounded-full bg-cobalt"></span> : null}
            </span>
            <span className="min-w-0 flex-1">
              <span className="flex flex-wrap items-baseline gap-x-3 gap-y-0.5 pr-24">
                <span className={'font-bold ' + (none ? 'text-muted' : 'text-ink')}>{o.title}</span>
                {o.premium != null ? (
                  <span className="text-base font-bold tabular-nums tracking-tight text-ink">
                    {L.fmtEUR(o.premium)}<span className="text-xs font-medium text-muted">{freqLabel(o.frequency, lang)}</span>
                  </span>
                ) : null}
              </span>
              <span className="mt-0.5 block text-sm text-muted">{none ? o.desc : t('booking.protection.multiRisk.includes')}</span>
            </span>
            {o.recommended ? <span className="absolute right-3 top-3"><Badge variant="coral">{t('booking.protection.recommended')}</Badge></span> : null}
          </button>
        );
      })}
      <p className="text-xs text-muted">{t('booking.protection.precontractual')}</p>
    </div>
  );
}

/* ---------- step 5: protection — SLOT #1, wired to Sherpa /api/quote ---------- */
function Step5Protection({ draft, dispatch }) {
  const { t } = useLang();
  const [decided, setDecided] = useState(draft.protection ? draft.protection.name : null);
  const [pendingSelection, setPendingSelection] = useState(draft.protection || undefined); // undefined = no decision yet
  const [loading, setLoading] = useState(true);
  const [quoteId, setQuoteId] = useState(null);
  const [plans, setPlans] = useState([]);
  const [error, setError] = useState(null);

  useEffect(function () {
    let on = true;
    setLoading(true); setError(null);
    window.VolaireSherpa.quote(draft).then(function (res) {
      if (!on) return;
      setQuoteId(res.quoteId);
      setPlans(res.plans || []);
      setLoading(false);
    }).catch(function (err) {
      if (!on) return;
      setError(err && err.message ? err.message : String(err));
      setPendingSelection(null); // allow continuing without insurance on error
      setDecided('none');
      setLoading(false);
    });
    return function () { on = false; };
  }, []);

  const hasDecision = pendingSelection !== undefined;

  function handleSelection(selection, optionId) {
    setPendingSelection(selection); // null = "Sans assurance"
    setDecided(optionId);
  }
  function commit() {
    if (pendingSelection) dispatch({ type: 'ATTACH_PROTECTION', protection: pendingSelection });
    else dispatch({ type: 'REMOVE_PROTECTION' });
    dispatch({ type: 'SET_STEP', step: 6 });
  }

  return (
    <div>
      <h1 className="text-2xl font-bold tracking-tight text-ink">{t('booking.protection.stepTitle')}</h1>
      <section id="protection-embed-slot" className="mt-4 min-h-[420px] rounded-xl border border-line bg-white p-6">
        {loading ? (
          <div className="flex min-h-[360px] items-center justify-center" role="status" aria-label="Chargement">
            <span className="h-8 w-8 animate-spin rounded-full border-2 border-line border-t-cobalt"></span>
          </div>
        ) : error ? (
          <div className="flex min-h-[360px] flex-col items-center justify-center gap-3 text-center">
            <Icon name="info" size={28} className="text-muted/60"></Icon>
            <p className="max-w-md text-sm text-muted">{t('booking.protection.unavailable')}</p>
          </div>
        ) : (
          <ProtectionOffer quoteId={quoteId} plans={plans} value={decided} onSelectionChange={handleSelection}></ProtectionOffer>
        )}
      </section>
      <StepFooter onBack={function () { dispatch({ type: 'SET_STEP', step: 4 }); }}
        onNext={commit} nextDisabled={!hasDecision || loading}></StepFooter>
    </div>
  );
}

/* ---------- step 6: payment ---------- */
function Step6Payment({ draft, dispatch }) {
  const { t, lang } = useLang();
  const [method, setMethod] = useState(draft.payment || 'card');
  const [terms, setTerms] = useState(false);
  const [privacy, setPrivacy] = useState(false);
  const [card, setCard] = useState({ number: '', expiry: '', cvc: '', holder: '' });
  const [processing, setProcessing] = useState(false);
  const total = bookingTotal(draft);
  const canPay = terms && privacy && !processing && (method !== 'card' || (card.number && card.expiry && card.cvc && card.holder));

  function pay() {
    if (!canPay) return;
    setProcessing(true);
    // Flight order payment (demo) runs first; the travel-protection policy is
    // then bound separately via Sherpa, mirroring the embed's own bind step.
    L.mockAsync(1500).then(function () {
      // Sign the customer in before binding so the policy's externalClientId
      // matches the one the customer portal uses later (session email).
      if (draft.passenger.createAccount || !L.getSession()) {
        L.setSession({ firstName: draft.passenger.firstName || 'Camille', lastName: draft.passenger.lastName || 'Laurent', email: draft.passenger.email });
      }
      const bindProtection = (draft.protection && draft.protection.quoteId)
        ? window.VolaireSherpa.buy(draft, draft.protection).then(function (res) {
            return Object.assign({}, draft.protection, { policyId: res.policyId, policyNumber: res.policyNumber });
          }).catch(function () {
            showToast(t('booking.protection.bindFailed'));
            return draft.protection; // keep flight booking; protection retry handled in portal
          })
        : Promise.resolve(draft.protection || undefined);

      bindProtection.then(function (protection) {
        const pnr = L.generatePNR();
        const booking = {
          pnr: pnr, status: 'confirmed', tripType: draft.tripType,
          outbound: draft.outbound, inbound: draft.inbound || undefined,
          fareFamily: draft.fareFamily, passenger: draft.passenger,
          seats: draft.seats, extras: draft.extras,
          protection: protection || undefined,
          total: total, bookedAt: new Date().toISOString(),
        };
        L.saveTrip(booking);
        dispatch({ type: 'SET_PAYMENT', payload: { payment: method, termsAccepted: true, privacyAccepted: true } });
        dispatch({ type: 'CONFIRM_BOOKING', pnr: pnr });
        window.location.hash = '/booking?step=success';
        window.scrollTo(0, 0);
      });
    });
  }

  const methods = [
    { v: 'card', l: t('booking.payment.card'), icon: 'card' },
    { v: 'paypal', l: t('booking.payment.paypal'), icon: 'wallet' },
    { v: 'apple-pay', l: t('booking.payment.applePay'), icon: 'phone' },
  ];
  return (
    <div>
      <h1 className="text-2xl font-bold tracking-tight text-ink">{t('booking.payment.title')}</h1>
      <p className="mt-1 text-sm text-muted">{t('booking.payment.note')}</p>
      <div className="mt-4 rounded-xl border border-line bg-white p-5">
        <div role="radiogroup" aria-label={t('booking.payment.title')} className="grid grid-cols-1 gap-2 sm:grid-cols-3">
          {methods.map(function (m) {
            const on = method === m.v;
            return (
              <button key={m.v} role="radio" aria-checked={on}
                className={'flex items-center justify-center gap-2 rounded-lg border px-4 py-3 text-sm font-semibold ' + (on ? 'border-2 border-cobalt bg-cobalt/5 text-cobalt' : 'border-line text-ink hover:border-cobalt/50')}
                onClick={function () { setMethod(m.v); }}>
                <Icon name={m.icon} size={18}></Icon>{m.l}
              </button>
            );
          })}
        </div>
        {method === 'card' ? (
          <div className="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-4">
            <Field label={t('booking.payment.cardNumber')} className="sm:col-span-4">
              <input className={inputCls + ' tabular-nums'} inputMode="numeric" placeholder="4970 10•• •••• ••••" value={card.number}
                onChange={function (e) { setCard(Object.assign({}, card, { number: e.target.value })); }} />
            </Field>
            <Field label={t('booking.payment.expiry')} className="sm:col-span-1">
              <input className={inputCls + ' tabular-nums'} placeholder="MM/AA" value={card.expiry}
                onChange={function (e) { setCard(Object.assign({}, card, { expiry: e.target.value })); }} />
            </Field>
            <Field label={t('booking.payment.cvc')} className="sm:col-span-1">
              <input className={inputCls + ' tabular-nums'} inputMode="numeric" placeholder="123" value={card.cvc}
                onChange={function (e) { setCard(Object.assign({}, card, { cvc: e.target.value })); }} />
            </Field>
            <Field label={t('booking.payment.holder')} className="sm:col-span-2">
              <input className={inputCls} placeholder="C. LAURENT" value={card.holder}
                onChange={function (e) { setCard(Object.assign({}, card, { holder: e.target.value })); }} />
            </Field>
          </div>
        ) : (
          <p className="mt-4 rounded-lg bg-page px-4 py-3 text-sm text-muted">{method === 'paypal' ? 'PayPal' : 'Apple Pay'} — {lang === 'en' ? 'visual demo' : lang === 'es' ? 'demo visual' : 'démo visuelle'}.</p>
        )}
        <div className="mt-5 flex flex-col gap-2.5 border-t border-line pt-4">
          <label className="flex cursor-pointer items-start gap-2.5 text-sm text-ink">
            <input type="checkbox" checked={terms} required className="mt-0.5 h-4 w-4 rounded border-line text-cobalt focus:ring-cobalt"
              onChange={function (e) { setTerms(e.target.checked); }} />
            <span>{t('booking.payment.terms')} <Link to="/about" className="text-cobalt underline">(CGV)</Link></span>
          </label>
          <label className="flex cursor-pointer items-start gap-2.5 text-sm text-ink">
            <input type="checkbox" checked={privacy} required className="mt-0.5 h-4 w-4 rounded border-line text-cobalt focus:ring-cobalt"
              onChange={function (e) { setPrivacy(e.target.checked); }} />
            <span>{t('booking.payment.privacy')} <Link to="/about" className="text-cobalt underline">→</Link></span>
          </label>
        </div>
        {draft.protection ? (
          <p className="mt-3 flex items-center gap-2 rounded-lg bg-page px-4 py-3 text-sm text-muted">
            <Icon name="shield" size={16} className="shrink-0 text-success"></Icon>
            {t('booking.summary.protection')} : {L.fmtEUR(draft.protection.premium)} — {t('booking.summary.protection.separate')}.
          </p>
        ) : null}
        <div className="mt-5 flex flex-col items-stretch gap-2 sm:flex-row sm:items-center sm:justify-between">
          <span className="flex items-center gap-1.5 text-xs text-muted"><Icon name="lock" size={14}></Icon>{t('booking.payment.secure')}</span>
          <button onClick={pay} disabled={!canPay}
            className="flex items-center justify-center gap-2 rounded-lg bg-cobalt px-8 py-3.5 text-sm font-bold text-white hover:bg-cobaltDark disabled:cursor-not-allowed disabled:opacity-40">
            {processing ? <span className="h-4 w-4 animate-spin rounded-full border-2 border-white/40 border-t-white"></span> : null}
            {processing ? t('booking.payment.processing') : t('booking.payment.cta') + ' ' + L.fmtEUR(total)}
          </button>
        </div>
      </div>
      <StepFooter onBack={function () { dispatch({ type: 'SET_STEP', step: 5 }); }} onNext={pay} nextDisabled={!canPay}
        nextLabel={t('booking.payment.cta') + ' ' + L.fmtEUR(total)}></StepFooter>
    </div>
  );
}

/* ---------- confirmation ---------- */
function Confirmation({ draft, dispatch }) {
  const { t, lang } = useLang();
  const trip = L.findTrip(draft.pnr) || null;
  if (!trip) return null;
  return (
    <div className="mx-auto max-w-2xl">
      <div className="rounded-xl border border-line bg-white p-6 text-center sm:p-8">
        <span className="mx-auto flex h-14 w-14 items-center justify-center rounded-full bg-success/10 text-success"><Icon name="check" size={28}></Icon></span>
        <h1 className="mt-4 text-2xl font-bold tracking-tight text-ink">{t('booking.confirm.title')}</h1>
        <p className="mt-2 text-sm text-muted">{t('booking.confirm.reference')}</p>
        <p className="text-3xl font-bold tabular-nums tracking-widest text-cobalt">{trip.pnr}</p>
        <div className="mt-5 flex flex-col gap-2 text-left">
          <FlightRecapStatic f={trip.outbound} seat={(trip.seats.find(function (s) { return s.flightId === 'out'; }) || {}).seat} lang={lang}></FlightRecapStatic>
          {trip.inbound ? <FlightRecapStatic f={trip.inbound} seat={(trip.seats.find(function (s) { return s.flightId === 'in'; }) || {}).seat} lang={lang}></FlightRecapStatic> : null}
        </div>
        <p className="mt-4 text-sm text-muted">{t('booking.confirm.emailNote')} <span className="font-semibold text-ink">{trip.passenger.email || 'camille.laurent@example.fr'}</span></p>
        <p className="mt-1 flex items-center justify-center gap-1.5 text-xs font-medium text-success"><Icon name="check" size={14}></Icon>{t('booking.confirm.freeCancel')}</p>
        {trip.protection ? (
          <p className="mt-4 flex items-start gap-2 rounded-lg bg-cobalt/5 px-4 py-3 text-left text-sm text-ink">
            <Icon name="shield" size={16} className="mt-0.5 shrink-0 text-cobalt"></Icon>
            {t('booking.confirm.protectionNote')}
          </p>
        ) : null}
        <div className="mt-6 flex flex-col justify-center gap-2 sm:flex-row">
          <button onClick={function () { const pnr = trip.pnr; dispatch({ type: 'RESET' }); window.VolaireDraft.clearDraft(); navigate('/account/trips/' + pnr); }}
            className="rounded-lg bg-cobalt px-6 py-3 text-sm font-bold text-white hover:bg-cobaltDark">{t('booking.confirm.viewTrip')}</button>
          <button onClick={function () { dispatch({ type: 'RESET' }); window.VolaireDraft.clearDraft(); navigate('/'); }}
            className="rounded-lg border border-line px-6 py-3 text-sm font-semibold text-ink hover:border-cobalt">{t('booking.confirm.backHome')}</button>
        </div>
      </div>
    </div>
  );
}
function FlightRecapStatic({ f, seat, lang }) {
  return (
    <div className="flex items-center justify-between gap-3 rounded-lg border border-line bg-page/60 px-4 py-3">
      <span className="text-sm font-bold tabular-nums text-ink">{L.fmtTime(f.departTime)} {f.origin} → {L.fmtTime(f.arriveTime)} {f.destination}</span>
      <span className="text-xs capitalize text-muted">{L.fmtDateShort(f.departTime, lang)} · {f.flightNumber}{seat ? ' · ' + seat : ''}</span>
    </div>
  );
}

/* ---------- wizard shell ---------- */
function BookingPage() {
  const { t } = useLang();
  const route = useRoute();
  const [draft, dispatch] = useBookingDraft();
  const liveRef = useRef(null);
  const isSuccess = draft.step === 'success' && route.query.step === 'success';

  useEffect(function () {
    if (liveRef.current) liveRef.current.textContent = typeof draft.step === 'number' ? t(STEP_KEYS[draft.step - 1]) : '';
  }, [draft.step]);

  if (!draft.outbound) {
    return (
      <main className="mx-auto max-w-6xl px-4 py-16 text-center">
        <span className="mx-auto flex h-14 w-14 items-center justify-center rounded-full bg-cobalt/10 text-cobalt"><Icon name="plane" size={26}></Icon></span>
        <h1 className="mt-4 text-2xl font-bold tracking-tight text-ink">{t('booking.empty.title')}</h1>
        <p className="mt-2 text-sm text-muted">{t('booking.empty.body')}</p>
        <Link to="/" className="mt-5 inline-block rounded-lg bg-cobalt px-6 py-3 text-sm font-bold text-white hover:bg-cobaltDark">{t('booking.empty.cta')}</Link>
      </main>
    );
  }

  if (draft.step === 'success' || isSuccess) {
    return <main className="mx-auto max-w-6xl px-4 py-10"><Confirmation draft={draft} dispatch={dispatch}></Confirmation></main>;
  }

  const steps = { 1: Step1Flights, 2: Step2Passenger, 3: Step3Seats, 4: Step4Options, 5: Step5Protection, 6: Step6Payment };
  const StepComp = steps[draft.step] || Step1Flights;

  return (
    <main className="mx-auto max-w-6xl px-4 pb-32 pt-6 lg:pb-10">
      <span className="sr-only" aria-live="polite" ref={liveRef}></span>
      <div className="sticky top-[105px] z-30 -mx-1 bg-page/95 px-1 py-2 backdrop-blur md:top-[118px]">
        <div className="rounded-xl border border-line bg-white px-4 py-2.5">
          <ProgressBar step={draft.step} onJump={function (n) { dispatch({ type: 'SET_STEP', step: n }); }}></ProgressBar>
        </div>
      </div>
      <div className="mt-5 grid gap-6 lg:grid-cols-[1fr_320px]">
        <div data-screen-label={'Booking step ' + draft.step}>
          <StepComp draft={draft} dispatch={dispatch}></StepComp>
        </div>
        <SummaryRail draft={draft}></SummaryRail>
      </div>
    </main>
  );
}

Object.assign(window, { ProtectionOffer, freqLabel, Step5Protection, Step6Payment, Confirmation, BookingPage, FlightRecapStatic });
