/* Volaire — /booking: 6-step wizard, summary rail, protection slot #1, confirmation */
const { loadDraft, saveDraft, clearDraft } = window.VolaireDraft;

/* ---------- reducer ---------- */
function bookingReducer(state, action) {
  switch (action.type) {
    case 'SET_STEP': return Object.assign({}, state, { step: action.step });
    case 'SET_FLIGHTS': return Object.assign({}, state, { outbound: action.outbound, inbound: action.inbound, tripType: action.tripType });
    case 'SET_FARE': return Object.assign({}, state, { fareFamily: action.fareFamily });
    case 'SET_PASSENGER': return Object.assign({}, state, { passenger: Object.assign({}, state.passenger, action.passenger) });
    case 'SET_SEAT': {
      const seats = state.seats.filter(function (s) { return s.flightId !== action.seat.flightId; });
      if (action.seat.seat) seats.push(action.seat);
      return Object.assign({}, state, { seats: seats });
    }
    case 'SET_EXTRAS': return Object.assign({}, state, { extras: Object.assign({}, state.extras, action.extras) });
    case 'ATTACH_PROTECTION': return Object.assign({}, state, { protection: action.protection });
    case 'REMOVE_PROTECTION': return Object.assign({}, state, { protection: null });
    case 'SET_PAYMENT': return Object.assign({}, state, action.payload);
    case 'CONFIRM_BOOKING': return Object.assign({}, state, { step: 'success', pnr: action.pnr });
    case 'RESET': return JSON.parse(JSON.stringify(window.VolaireDraft.EMPTY_DRAFT));
    default: return state;
  }
}

function useBookingDraft() {
  const [draft, dispatch] = React.useReducer(bookingReducer, null, loadDraft);
  useEffect(function () { saveDraft(draft); }, [draft]);
  return [draft, dispatch];
}

/* ---------- totals ---------- */
function flightCount(d) { return d.inbound ? 2 : 1; }
function fareTotal(d) {
  if (!d.outbound || !d.fareFamily) return 0;
  let s = d.outbound.fares[d.fareFamily].price;
  if (d.inbound) s += d.inbound.fares[d.fareFamily].price;
  return s;
}
function seatsTotal(d) { return d.seats.reduce(function (s, x) { return s + (x.fee || 0); }, 0); }
function extrasTotal(d) {
  const n = flightCount(d), e = d.extras, P = L.OPTION_PRICES, inc = L.FARE_RULES[d.fareFamily || 'light'];
  let s = 0;
  if (!inc.checkedBag) s += (e.checkedBags || 0) * P.checkedBag * n;
  s += (e.extraBags || 0) * P.extraBag * n;
  if (e.priority && !inc.priority) s += P.priority * n;
  if (e.meal) s += P.meal * n;
  if (e.sportsEquipment) s += P.sports;
  return s;
}
function bookingTotal(d) { return fareTotal(d) + seatsTotal(d) + extrasTotal(d); }

/* ---------- progress bar ---------- */
const STEP_KEYS = ['booking.step1', 'booking.step2', 'booking.step3', 'booking.step4', 'booking.step5', 'booking.step6'];
function ProgressBar({ step, onJump }) {
  const { t } = useLang();
  const cur = step === 'success' ? 7 : step;
  return (
    <ol className="flex flex-wrap items-center gap-x-1 gap-y-2" aria-label={t('booking.title')}>
      {STEP_KEYS.map(function (k, i) {
        const n = i + 1, done = cur > n, active = cur === n;
        return (
          <li key={k} className="flex items-center gap-1">
            <button disabled={!done} onClick={function () { if (done) onJump(n); }}
              aria-current={active ? 'step' : undefined}
              className={'flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-semibold sm:text-[13px] ' +
                (active ? 'bg-cobalt text-white' : done ? 'text-cobalt hover:bg-cobalt/10' : 'text-muted/60')}>
              <span className={'flex h-4.5 w-4.5 items-center justify-center ' + (done ? 'text-success' : '')}>
                {done ? <Icon name="check" size={14}></Icon> : <span className="tabular-nums">{n}</span>}
              </span>
              <span className="hidden sm:inline">{t(k)}</span>
            </button>
            {n < 6 ? <span className="h-px w-3 bg-line sm:w-5"></span> : null}
          </li>
        );
      })}
    </ol>
  );
}

/* ---------- summary rail ---------- */
function SummaryFlightLine({ f, fare }) {
  return (
    <div className="flex items-center justify-between gap-2 text-sm">
      <span className="flex items-center gap-1.5 tabular-nums text-ink">
        <span className="font-semibold">{f.origin}</span>
        <Icon name="arrowRight" size={12} className="text-muted"></Icon>
        <span className="font-semibold">{f.destination}</span>
        <span className="text-xs text-muted">{L.fmtTime(f.departTime)}</span>
      </span>
      <span className="font-semibold tabular-nums">{L.fmtEUR(f.fares[fare].price)}</span>
    </div>
  );
}
function SummaryRail({ draft, mobileCta, onCta, ctaLabel, ctaDisabled }) {
  const { t } = useLang();
  const [openMobile, setOpenMobile] = useState(false);
  const total = bookingTotal(draft);
  const body = (
    <div className="flex flex-col gap-3">
      <h2 className="text-sm font-bold uppercase tracking-wider text-muted">{t('booking.summary.title')}</h2>
      {draft.outbound ? (
        <div className="flex flex-col gap-1.5 border-b border-line pb-3">
          <SummaryFlightLine f={draft.outbound} fare={draft.fareFamily}></SummaryFlightLine>
          {draft.inbound ? <SummaryFlightLine f={draft.inbound} fare={draft.fareFamily}></SummaryFlightLine> : null}
          <div className="mt-1"><FareFamilyPill fare={draft.fareFamily}></FareFamilyPill></div>
        </div>
      ) : null}
      {seatsTotal(draft) > 0 || draft.seats.length ? (
        <div className="flex items-center justify-between border-b border-line pb-3 text-sm">
          <span className="text-muted">{t('booking.summary.seats')} <span className="tabular-nums">{draft.seats.map(function (s) { return s.seat; }).join(' · ')}</span></span>
          <span className="font-semibold tabular-nums">{seatsTotal(draft) ? L.fmtEUR(seatsTotal(draft)) : t('booking.seats.included')}</span>
        </div>
      ) : null}
      {extrasTotal(draft) > 0 ? (
        <div className="flex items-center justify-between border-b border-line pb-3 text-sm">
          <span className="text-muted">{t('booking.summary.options')}</span>
          <span className="font-semibold tabular-nums">{L.fmtEUR(extrasTotal(draft))}</span>
        </div>
      ) : null}
      {draft.protection ? (
        <div className="flex items-start justify-between gap-2 border-b border-line pb-3 text-sm">
          <span className="flex items-center gap-1.5 text-muted"><Icon name="shield" size={14} className="text-success"></Icon>{t('booking.summary.protection')}</span>
          <span className="text-right">
            <span className="block font-semibold tabular-nums">{L.fmtEUR(draft.protection.premium)}</span>
            <span className="block text-xs text-muted">{t('booking.summary.protection.separate')}</span>
          </span>
        </div>
      ) : null}
      <div className="flex items-baseline justify-between" aria-live="polite">
        <span className="text-sm font-bold text-ink">{t('booking.summary.total')}</span>
        <span className="text-2xl font-bold tabular-nums tracking-tight text-ink">{L.fmtEUR(total)}</span>
      </div>
    </div>
  );
  return (
    <React.Fragment>
      <aside className="hidden lg:block">
        <div className="sticky top-36 rounded-xl border border-line bg-white p-5">{body}</div>
      </aside>
      {/* mobile collapsible bottom bar */}
      <div className="fixed bottom-0 left-0 right-0 z-40 border-t border-line bg-white lg:hidden">
        {openMobile ? <div className="border-b border-line p-4">{body}</div> : null}
        <div className="flex items-center justify-between gap-3 px-4 py-3">
          <button className="flex items-center gap-1 text-left" onClick={function () { setOpenMobile(!openMobile); }} aria-expanded={openMobile}>
            <div>
              <p className="text-[11px] font-semibold uppercase tracking-wide text-muted">{t('booking.summary.total')}</p>
              <p className="text-lg font-bold tabular-nums text-ink">{L.fmtEUR(total)}</p>
            </div>
            <Icon name="chevronDown" size={16} className={'text-muted ' + (openMobile ? '' : 'rotate-180')}></Icon>
          </button>
          {mobileCta ? (
            <button onClick={onCta} disabled={ctaDisabled}
              className="rounded-lg bg-cobalt px-6 py-2.5 text-sm font-bold text-white disabled:opacity-40">{ctaLabel || t('common.continue')}</button>
          ) : null}
        </div>
      </div>
    </React.Fragment>
  );
}

/* ---------- step footer ---------- */
function StepFooter({ onBack, onNext, nextLabel, nextDisabled }) {
  const { t } = useLang();
  return (
    <div className="mt-6 flex items-center justify-between gap-3">
      {onBack ? (
        <button onClick={onBack} className="rounded-lg px-4 py-3 text-sm font-semibold text-muted hover:bg-white hover:text-ink">
          ← {t('common.back')}
        </button>
      ) : <span></span>}
      <button onClick={onNext} disabled={nextDisabled}
        className="w-full rounded-lg bg-cobalt px-8 py-3 text-sm font-bold text-white transition-colors hover:bg-cobaltDark disabled:cursor-not-allowed disabled:opacity-40 sm:w-auto">
        {nextLabel || t('common.continue')}
      </button>
    </div>
  );
}

/* ---------- step 1: flights review ---------- */
function FlightRecap({ f, fare, label }) {
  const { t, lang } = useLang();
  return (
    <div className="rounded-xl border border-line bg-white p-4">
      <div className="flex items-center justify-between gap-2">
        <span className="text-xs font-bold uppercase tracking-wider text-muted">{label}</span>
        <Link to="/search" className="text-sm font-semibold text-cobalt hover:underline">{t('common.edit')}</Link>
      </div>
      <div className="mt-2 flex flex-wrap items-center gap-x-5 gap-y-2">
        <p className="text-xl font-bold tabular-nums tracking-tight text-ink">
          {L.fmtTime(f.departTime)} {f.origin} <span className="font-normal text-muted">→</span> {L.fmtTime(f.arriveTime)} {f.destination}
        </p>
        <FareFamilyPill fare={fare}></FareFamilyPill>
      </div>
      <p className="mt-1 text-sm capitalize text-muted">{L.fmtDateLong(f.departTime, lang)} · {f.flightNumber} · {f.aircraft} · {L.fmtDuration(f.durationMin)}</p>
    </div>
  );
}
function Step1Flights({ draft, dispatch }) {
  const { t } = useLang();
  return (
    <div>
      <h1 className="text-2xl font-bold tracking-tight text-ink">{t('booking.step1.title')}</h1>
      <div className="mt-4 flex flex-col gap-3">
        <FlightRecap f={draft.outbound} fare={draft.fareFamily} label={t('booking.seats.outbound')}></FlightRecap>
        {draft.inbound ? <FlightRecap f={draft.inbound} fare={draft.fareFamily} label={t('booking.seats.return')}></FlightRecap> : null}
      </div>
      <StepFooter onNext={function () { dispatch({ type: 'SET_STEP', step: 2 }); }}></StepFooter>
    </div>
  );
}

/* ---------- step 2: passenger ---------- */
function Step2Passenger({ draft, dispatch }) {
  const { t } = useLang();
  const session = useSession();
  const p = draft.passenger;
  function set(k, v) { dispatch({ type: 'SET_PASSENGER', passenger: (function () { const o = {}; o[k] = v; return o; })() }); }
  const valid = p.firstName && p.lastName && p.dateOfBirth && p.email && p.phone;
  return (
    <div>
      <h1 className="text-2xl font-bold tracking-tight text-ink">{t('booking.passenger.title')}</h1>
      <p className="mt-1 text-sm text-muted">{t('booking.passenger.note')}</p>
      <form className="mt-4 rounded-xl border border-line bg-white p-5" onSubmit={function (e) { e.preventDefault(); if (valid) dispatch({ type: 'SET_STEP', step: 3 }); }}>
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-6">
          <Field label={t('booking.passenger.salutation')} className="sm:col-span-1">
            <select className={inputCls} value={p.salutation} onChange={function (e) { set('salutation', e.target.value); }}>
              <option value="Mme">{t('booking.passenger.mrs')}</option>
              <option value="M.">{t('booking.passenger.mr')}</option>
            </select>
          </Field>
          <Field label={t('booking.passenger.firstName')} className="sm:col-span-2">
            <input className={inputCls} value={p.firstName} required autoComplete="given-name" onChange={function (e) { set('firstName', e.target.value); }} />
          </Field>
          <Field label={t('booking.passenger.lastName')} className="sm:col-span-3">
            <input className={inputCls} value={p.lastName} required autoComplete="family-name" onChange={function (e) { set('lastName', e.target.value); }} />
          </Field>
          <Field label={t('booking.passenger.dateOfBirth')} className="sm:col-span-3">
            <input type="date" className={inputCls + ' tabular-nums'} value={p.dateOfBirth} required max={L.todayISO(0)} onChange={function (e) { set('dateOfBirth', e.target.value); }} />
          </Field>
          <Field label={t('booking.passenger.nationality')} className="sm:col-span-3">
            <input className={inputCls} value={p.nationality} placeholder="Française" onChange={function (e) { set('nationality', e.target.value); }} />
          </Field>
          <Field label={t('booking.passenger.email')} className="sm:col-span-3">
            <input type="email" className={inputCls} value={p.email} required autoComplete="email" onChange={function (e) { set('email', e.target.value); }} />
          </Field>
          <Field label={t('booking.passenger.phone')} className="sm:col-span-3">
            <input type="tel" className={inputCls + ' tabular-nums'} value={p.phone} required autoComplete="tel" onChange={function (e) { set('phone', e.target.value); }} />
          </Field>
          <Field label={t('booking.passenger.loyalty')} className="sm:col-span-3">
            <input className={inputCls + ' tabular-nums'} value={p.loyaltyNumber} placeholder="VC 000 000" onChange={function (e) { set('loyaltyNumber', e.target.value); }} />
          </Field>
        </div>
        {!session ? (
          <label className="mt-4 flex cursor-pointer items-start gap-2.5 text-sm text-ink">
            <input type="checkbox" checked={!!p.createAccount} className="mt-0.5 h-4 w-4 rounded border-line text-cobalt focus:ring-cobalt"
              onChange={function (e) { set('createAccount', e.target.checked); }} />
            {t('booking.passenger.createAccount')}
          </label>
        ) : null}
        <StepFooter onBack={function () { dispatch({ type: 'SET_STEP', step: 1 }); }}
          onNext={function () { if (valid) dispatch({ type: 'SET_STEP', step: 3 }); }} nextDisabled={!valid}></StepFooter>
      </form>
    </div>
  );
}

/* ---------- step 3: seats ---------- */
function Step3Seats({ draft, dispatch }) {
  const { t } = useLang();
  const [tab, setTab] = useState('out');
  const legs = [{ id: 'out', f: draft.outbound, label: t('booking.seats.outbound') }];
  if (draft.inbound) legs.push({ id: 'in', f: draft.inbound, label: t('booking.seats.return') });
  const leg = legs.find(function (x) { return x.id === tab; }) || legs[0];
  const sel = draft.seats.find(function (s) { return s.flightId === leg.id; });
  const initials = ((draft.passenger.firstName || 'C')[0] + (draft.passenger.lastName || 'L')[0]).toUpperCase();
  function pick(seatId, fee) { dispatch({ type: 'SET_SEAT', seat: { flightId: leg.id, seat: seatId, fee: fee } }); }
  return (
    <div>
      <h1 className="text-2xl font-bold tracking-tight text-ink">{t('booking.seats.title')}</h1>
      {legs.length > 1 ? (
        <div role="tablist" className="mt-3 flex w-fit rounded-lg border border-line bg-white p-0.5">
          {legs.map(function (lg) {
            const s = draft.seats.find(function (x) { return x.flightId === lg.id; });
            return (
              <button key={lg.id} role="tab" aria-selected={tab === lg.id}
                className={'rounded-md px-4 py-1.5 text-sm font-medium ' + (tab === lg.id ? 'bg-cobalt text-white' : 'text-muted hover:text-ink')}
                onClick={function () { setTab(lg.id); }}>
                {lg.label}{s ? <span className="ml-1.5 tabular-nums opacity-80">{s.seat}</span> : null}
              </button>
            );
          })}
        </div>
      ) : null}
      <div className="mt-4 rounded-xl border border-line bg-white p-4 sm:p-5">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <p className="text-sm text-muted">{leg.f.flightNumber} · {leg.f.origin} → {leg.f.destination} · {leg.f.aircraft}</p>
          <p className="text-sm font-semibold text-ink" aria-live="polite">
            {sel ? t('booking.seats.selected') + ' : ' : ''}<span className="tabular-nums text-cobalt">{sel ? sel.seat : ''}</span>
            {sel ? <span className="text-muted"> · {sel.fee ? L.fmtEUR(sel.fee) : t('booking.seats.included')}</span> : null}
          </p>
        </div>
        <div className="mt-4">
          <SeatMap flight={leg.f} fareFamily={draft.fareFamily} selected={sel ? sel.seat : null} onSelect={pick} initials={initials}></SeatMap>
        </div>
        <div className="mt-4 flex flex-wrap items-center gap-3 border-t border-line pt-4">
          <button className="rounded-lg border border-line px-4 py-2 text-sm font-semibold text-ink hover:border-cobalt"
            onClick={function () {
              legs.forEach(function (lg) { dispatch({ type: 'SET_SEAT', seat: { flightId: lg.id, seat: null } }); });
              showToast(t('booking.seats.chooseForMe.note'));
            }}>
            {t('booking.seats.chooseForMe')}
          </button>
          <span className="text-xs text-muted">{t('booking.seats.chooseForMe.note')}</span>
        </div>
      </div>
      <StepFooter onBack={function () { dispatch({ type: 'SET_STEP', step: 2 }); }}
        onNext={function () {
          if (legs.length > 1 && tab === 'out' && !draft.seats.find(function (s) { return s.flightId === 'in'; }) && sel) { setTab('in'); return; }
          dispatch({ type: 'SET_STEP', step: 4 });
        }}></StepFooter>
    </div>
  );
}

/* ---------- step 4: options ---------- */
function OptionRow({ icon, title, desc, right, children }) {
  return (
    <div className="flex flex-col gap-3 rounded-xl border border-line bg-white p-4 sm:flex-row sm:items-center">
      <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-cobalt/10 text-cobalt"><Icon name={icon} size={20}></Icon></span>
      <div className="min-w-0 flex-1">
        <p className="font-semibold text-ink">{title}</p>
        <p className="text-sm text-muted">{desc}</p>
      </div>
      <div className="flex shrink-0 items-center gap-3">{right}{children}</div>
    </div>
  );
}
function Stepper({ value, onChange, max }) {
  return (
    <div className="flex items-center gap-1 rounded-lg border border-line">
      <button className="px-3 py-1.5 text-lg font-bold text-muted hover:text-cobalt disabled:opacity-30" disabled={value <= 0}
        onClick={function () { onChange(value - 1); }} aria-label="−">−</button>
      <span className="w-6 text-center text-sm font-bold tabular-nums">{value}</span>
      <button className="px-3 py-1.5 text-lg font-bold text-muted hover:text-cobalt disabled:opacity-30" disabled={value >= (max || 3)}
        onClick={function () { onChange(value + 1); }} aria-label="+">+</button>
    </div>
  );
}
function Toggle({ on, onChange, label }) {
  return (
    <button role="switch" aria-checked={on} aria-label={label}
      className={'relative h-7 w-12 rounded-full transition-colors ' + (on ? 'bg-cobalt' : 'bg-line')}
      onClick={function () { onChange(!on); }}>
      <span className={'absolute top-0.5 h-6 w-6 rounded-full bg-white shadow transition-all ' + (on ? 'left-[22px]' : 'left-0.5')}></span>
    </button>
  );
}
function Step4Options({ draft, dispatch }) {
  const { t } = useLang();
  const e = draft.extras, P = L.OPTION_PRICES, inc = L.FARE_RULES[draft.fareFamily], n = flightCount(draft);
  function set(k, v) { dispatch({ type: 'SET_EXTRAS', extras: (function () { const o = {}; o[k] = v; return o; })() }); }
  const per = ' / ' + t('booking.options.perFlight');
  return (
    <div>
      <h1 className="text-2xl font-bold tracking-tight text-ink">{t('booking.options.title')}</h1>
      <div className="mt-4 flex flex-col gap-3">
        <OptionRow icon="bag" title={t('booking.options.checkedBag')} desc={t('booking.options.checkedBag.desc')}
          right={inc.checkedBag
            ? <Badge variant="success">{t('booking.options.included')}</Badge>
            : <span className="text-sm font-semibold tabular-nums text-ink">{L.fmtEUR(P.checkedBag)}<span className="font-normal text-muted">{per}</span></span>}>
          {!inc.checkedBag ? <Stepper value={e.checkedBags || 0} max={2} onChange={function (v) { set('checkedBags', v); }}></Stepper> : null}
        </OptionRow>
        <OptionRow icon="bag" title={t('booking.options.extraBag')} desc={t('booking.options.extraBag.desc')}
          right={<span className="text-sm font-semibold tabular-nums text-ink">{L.fmtEUR(P.extraBag)}<span className="font-normal text-muted">{per}</span></span>}>
          <Stepper value={e.extraBags || 0} max={2} onChange={function (v) { set('extraBags', v); }}></Stepper>
        </OptionRow>
        <OptionRow icon="planeUp" title={t('booking.options.priority')} desc={t('booking.options.priority.desc')}
          right={inc.priority
            ? <Badge variant="gold">{t('booking.options.included')}</Badge>
            : <span className="text-sm font-semibold tabular-nums text-ink">{L.fmtEUR(P.priority)}<span className="font-normal text-muted">{per}</span></span>}>
          {!inc.priority ? <Toggle on={!!e.priority} onChange={function (v) { set('priority', v); }} label={t('booking.options.priority')}></Toggle> : null}
        </OptionRow>
        <div className="rounded-xl border border-line bg-white p-4">
          <div className="flex items-center gap-3">
            <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-cobalt/10 text-cobalt"><Icon name="meal" size={20}></Icon></span>
            <div className="flex-1">
              <p className="font-semibold text-ink">{t('booking.options.meal')}</p>
              <p className="text-sm text-muted">{t('booking.options.meal.desc')} · <span className="font-semibold tabular-nums text-ink">{L.fmtEUR(P.meal)}</span>{per}</p>
            </div>
          </div>
          <div role="radiogroup" aria-label={t('booking.options.meal')} className="mt-3 flex flex-wrap gap-2">
            {[{ v: null, l: t('booking.options.meal.none') }, { v: 'classic', l: t('booking.options.meal.classic') }, { v: 'vegetarian', l: t('booking.options.meal.vegetarian') }, { v: 'gluten-free', l: t('booking.options.meal.glutenFree') }].map(function (o) {
              const on = (e.meal || null) === o.v;
              return (
                <button key={String(o.v)} role="radio" aria-checked={on}
                  className={'rounded-lg border px-4 py-2 text-sm font-medium ' + (on ? 'border-cobalt bg-cobalt/10 text-cobalt' : 'border-line text-ink hover:border-cobalt/50')}
                  onClick={function () { set('meal', o.v); }}>{o.l}</button>
              );
            })}
          </div>
        </div>
        <OptionRow icon="bike" title={t('booking.options.sports')} desc={t('booking.options.sports.desc')}
          right={<span className="text-sm font-semibold tabular-nums text-ink">{L.fmtEUR(P.sports)}</span>}>
          <Toggle on={!!e.sportsEquipment} onChange={function (v) { set('sportsEquipment', v); }} label={t('booking.options.sports')}></Toggle>
        </OptionRow>
      </div>
      <StepFooter onBack={function () { dispatch({ type: 'SET_STEP', step: 3 }); }}
        onNext={function () { dispatch({ type: 'SET_STEP', step: 5 }); }}></StepFooter>
    </div>
  );
}

Object.assign(window, {
  bookingReducer, useBookingDraft, flightCount, fareTotal, seatsTotal, extrasTotal, bookingTotal,
  ProgressBar, SummaryRail, StepFooter, FlightRecap,
  Step1Flights, Step2Passenger, Step3Seats, Step4Options, OptionRow, Stepper, Toggle,
});
