// Booking flow: month calendar → time slot → details → pay or code → confirmed.
// Mock data only. No real payment or backend calls.

const { useState: bUseState, useEffect: bUseEffect, useMemo: bUseMemo, forwardRef: bForwardRef } = React;

// Local atoms (booking.jsx is its own script scope under Babel standalone, so
// we can't rely on app.jsx's Eyebrow/SectionTitle being visible here).
function Eyebrow({ children }) { return <div className="ps-eyebrow">{children}</div>; }
function SectionTitle({ children }) {
  if (typeof children === "string") {
    return <h2 className="ps-h2"><LocalMarkerText text={children} /></h2>;
  }
  return <h2 className="ps-h2">{children}</h2>;
}

// Same parser as app.jsx's MarkerText; local copy so this script doesn't
// depend on app.jsx loading first.
function LocalMarkerEm({ children }) {
  return <em className="ps-mk">{children}</em>;
}
function LocalMarkerText({ text }) {
  if (!text) return null;
  const parts = String(text).split(/(\*[^*]+\*)/g);
  return (
    <>
      {parts.map((p, i) => {
        if (p.length > 2 && p.startsWith("*") && p.endsWith("*")) {
          return <LocalMarkerEm key={i}>{p.slice(1, -1)}</LocalMarkerEm>;
        }
        return <React.Fragment key={i}>{p}</React.Fragment>;
      })}
    </>
  );
}

// ── Mock data ───────────────────────────────────────────────────────────────

// Slot pool by weekday (0=Sun..6=Sat). Empty arrays = day closed.
const SLOTS_BY_WEEKDAY = {
  0: [],
  1: ["10:00", "11:00", "12:00", "16:00", "17:00", "18:00"],
  2: ["10:00", "11:00", "15:00", "16:00", "17:00", "18:00"],
  3: ["10:00", "11:00", "12:00", "16:00", "17:00", "18:00"],
  4: ["10:00", "11:00", "15:00", "16:00", "17:00", "18:00"],
  5: ["10:00", "11:00", "12:00", "13:00"],
  6: [],
};

// Deterministic pseudo-random booked slots so the calendar feels real.
function bookedKeyFor(dateStr, hour) {
  let h = 0;
  const s = dateStr + hour;
  for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0;
  return (h & 0xff) < 90; // ~35% booked
}

const VALID_CODES = ["ALEJANDRA", "ABC123", "PSICO26"];

// ── Date helpers ────────────────────────────────────────────────────────────

function isoDate(d) {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}

function startOfMonth(d) { return new Date(d.getFullYear(), d.getMonth(), 1); }

function buildMonthGrid(viewDate) {
  // Monday-first grid, always 6 rows × 7 cols = 42 cells.
  const first = startOfMonth(viewDate);
  const dayOfWeek = (first.getDay() + 6) % 7; // 0 = Mon
  const start = new Date(first);
  start.setDate(first.getDate() - dayOfWeek);
  const cells = [];
  for (let i = 0; i < 42; i++) {
    const d = new Date(start);
    d.setDate(start.getDate() + i);
    cells.push(d);
  }
  return cells;
}

function isSameMonth(a, b) {
  return a.getMonth() === b.getMonth() && a.getFullYear() === b.getFullYear();
}

function isPast(d, today) {
  return d < today && !isSameDay(d, today);
}

function isSameDay(a, b) {
  return a.getFullYear() === b.getFullYear()
      && a.getMonth() === b.getMonth()
      && a.getDate() === b.getDate();
}

function formatLongDate(d, lang, t) {
  const months = t.booking.months;
  const day = d.getDate();
  const m = months[d.getMonth()];
  const y = d.getFullYear();
  if (lang === "en") {
    const M = m.charAt(0).toUpperCase() + m.slice(1);
    return `${M} ${day}, ${y}`;
  }
  return `${day} de ${m} de ${y}`;
}

// ── Calendar ────────────────────────────────────────────────────────────────

function MonthCalendar({ t, lang, view, setView, selected, setSelected }) {
  const today = bUseMemo(() => {
    const d = new Date();
    d.setHours(0, 0, 0, 0);
    return d;
  }, []);
  const cells = bUseMemo(() => buildMonthGrid(view), [view]);
  const monthLabel = t.booking.months[view.getMonth()];
  const monthCap = lang === "en"
    ? monthLabel.charAt(0).toUpperCase() + monthLabel.slice(1)
    : monthLabel;

  const canGoBack = !(view.getFullYear() === today.getFullYear() && view.getMonth() === today.getMonth());

  return (
    <div className="ps-cal">
      <div className="ps-cal-head">
        <button
          type="button"
          className="ps-cal-nav"
          onClick={() => setView(new Date(view.getFullYear(), view.getMonth() - 1, 1))}
          disabled={!canGoBack}
          aria-label={lang === "en" ? "Previous month" : "Mes anterior"}
        >‹</button>
        <div className="ps-cal-title">{monthCap} {view.getFullYear()}</div>
        <button
          type="button"
          className="ps-cal-nav"
          onClick={() => setView(new Date(view.getFullYear(), view.getMonth() + 1, 1))}
          aria-label={lang === "en" ? "Next month" : "Mes siguiente"}
        >›</button>
      </div>
      <div className="ps-cal-weekdays">
        {t.booking.weekdays.map((w) => <div key={w}>{w}</div>)}
      </div>
      <div className="ps-cal-grid">
        {cells.map((d, i) => {
          const inMonth = isSameMonth(d, view);
          const past = isPast(d, today);
          const weekday = d.getDay();
          const slots = SLOTS_BY_WEEKDAY[weekday] || [];
          const closed = slots.length === 0;
          const isSelected = selected && isSameDay(d, selected);
          const isToday = isSameDay(d, today);
          const disabled = past || closed || !inMonth;
          return (
            <button
              key={i}
              type="button"
              className={[
                "ps-cal-cell",
                inMonth ? "" : "ps-cal-cell-out",
                disabled ? "ps-cal-cell-dis" : "",
                isSelected ? "ps-cal-cell-sel" : "",
                isToday ? "ps-cal-cell-today" : "",
              ].join(" ")}
              disabled={disabled}
              onClick={() => setSelected(new Date(d))}
              aria-label={d.toDateString()}
            >
              <span className="ps-cal-cell-num">{d.getDate()}</span>
              {!disabled && inMonth && <span className="ps-cal-cell-dot" aria-hidden="true" />}
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ── Slot picker ─────────────────────────────────────────────────────────────

function SlotPicker({ t, selectedDate, slot, setSlot }) {
  if (!selectedDate) {
    return (
      <div className="ps-slots ps-slots-empty">
        <div className="ps-slots-empty-msg">
          {t.booking.subtitle}
        </div>
      </div>
    );
  }
  const slots = SLOTS_BY_WEEKDAY[selectedDate.getDay()] || [];
  if (slots.length === 0) {
    return <div className="ps-slots ps-slots-empty"><div className="ps-slots-empty-msg">{t.booking.noSlots}</div></div>;
  }
  const dateStr = isoDate(selectedDate);
  const groups = [
    { k: t.booking.timeMorning, slots: slots.filter((s) => parseInt(s, 10) < 12) },
    { k: t.booking.timeAfternoon, slots: slots.filter((s) => parseInt(s, 10) >= 12 && parseInt(s, 10) < 17) },
    { k: t.booking.timeEvening, slots: slots.filter((s) => parseInt(s, 10) >= 17) },
  ].filter((g) => g.slots.length);

  return (
    <div className="ps-slots">
      {groups.map((g) => (
        <div key={g.k} className="ps-slot-group">
          <div className="ps-slot-group-label">{g.k}</div>
          <div className="ps-slot-row">
            {g.slots.map((s) => {
              const booked = bookedKeyFor(dateStr, s);
              const active = slot === s;
              return (
                <button
                  key={s}
                  type="button"
                  className={[
                    "ps-slot",
                    booked ? "ps-slot-booked" : "",
                    active ? "ps-slot-active" : "",
                  ].join(" ")}
                  disabled={booked}
                  onClick={() => setSlot(s)}
                >
                  {s}
                </button>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

// ── Service picker (chip row) ───────────────────────────────────────────────

function ServicePicker({ t, lang, value, onChange }) {
  return (
    <div className="ps-service-picker">
      <div className="ps-field-label">{t.booking.pickService}</div>
      <div className="ps-service-chips">
        {t.services.items.map((s) => {
          const active = s.id === value;
          return (
            <button
              key={s.id}
              type="button"
              className={"ps-service-chip" + (active ? " ps-service-chip-active" : "")}
              onClick={() => onChange(s.id)}
            >
              <span className="ps-service-chip-name">{s.name}</span>
              <span className="ps-service-chip-price">
                {lang === "en" ? `$${s.price} ${t.misc.usd}` : `$${s.price.toLocaleString("es-MX")} ${t.misc.mxn}`}
              </span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ── Details form ────────────────────────────────────────────────────────────

function DetailsForm({ t, value, onChange }) {
  const set = (k) => (e) => onChange({ ...value, [k]: e.target.value });
  return (
    <div className="ps-details">
      <label className="ps-field ps-field-half">
        <span>{t.booking.details.name}</span>
        <input type="text" required value={value.name} onChange={set("name")} />
      </label>
      <label className="ps-field ps-field-half">
        <span>{t.booking.details.email}</span>
        <input type="email" required value={value.email} onChange={set("email")} />
      </label>
      <label className="ps-field ps-field-half">
        <span>{t.booking.details.phone}</span>
        <input type="tel" value={value.phone} onChange={set("phone")} />
      </label>
      <label className="ps-field ps-field-full">
        <span>{t.booking.details.note}</span>
        <textarea
          rows="3"
          value={value.note}
          onChange={set("note")}
          placeholder={t.booking.details.notePlaceholder}
        ></textarea>
      </label>
    </div>
  );
}

// ── Flow chooser (pay vs code) ──────────────────────────────────────────────

function FlowChooser({ t, value, onChange }) {
  return (
    <div className="ps-flow-choose">
      <div className="ps-field-label">{t.booking.flow.title}</div>
      <div className="ps-flow-cards">
        <button
          type="button"
          className={"ps-flow-card" + (value === "pay" ? " ps-flow-card-active" : "")}
          onClick={() => onChange("pay")}
        >
          <span className="ps-flow-card-radio" aria-hidden="true" />
          <span>
            <span className="ps-flow-card-label">{t.booking.flow.pay.label}</span>
            <span className="ps-flow-card-sub">{t.booking.flow.pay.sub}</span>
          </span>
        </button>
        <button
          type="button"
          className={"ps-flow-card" + (value === "code" ? " ps-flow-card-active" : "")}
          onClick={() => onChange("code")}
        >
          <span className="ps-flow-card-radio" aria-hidden="true" />
          <span>
            <span className="ps-flow-card-label">{t.booking.flow.code.label}</span>
            <span className="ps-flow-card-sub">{t.booking.flow.code.sub}</span>
          </span>
        </button>
      </div>
    </div>
  );
}

// ── Payment forms ───────────────────────────────────────────────────────────

function PayForm({ t, method, onConfirm }) {
  const submit = (e) => { e.preventDefault(); onConfirm(); };

  if (method === "card") {
    return (
      <form className="ps-pay-form" onSubmit={submit}>
        <label className="ps-field ps-field-full">
          <span>{t.booking.pay.card.number}</span>
          <input type="text" inputMode="numeric" placeholder="4242 4242 4242 4242" required />
        </label>
        <label className="ps-field ps-field-full">
          <span>{t.booking.pay.card.name}</span>
          <input type="text" required />
        </label>
        <label className="ps-field ps-field-half">
          <span>{t.booking.pay.card.exp}</span>
          <input type="text" placeholder="12 / 28" required />
        </label>
        <label className="ps-field ps-field-half">
          <span>{t.booking.pay.card.cvc}</span>
          <input type="text" inputMode="numeric" placeholder="123" required />
        </label>
        <button type="submit" className="ps-btn ps-btn-primary ps-btn-wide">{t.booking.pay.card.submit}</button>
      </form>
    );
  }
  if (method === "paypal") {
    return (
      <form className="ps-pay-form" onSubmit={submit}>
        <p className="ps-pay-sub">{t.booking.pay.paypal.sub}</p>
        <button type="submit" className="ps-btn ps-btn-primary ps-btn-wide">{t.booking.pay.paypal.submit}</button>
      </form>
    );
  }
  if (method === "bank") {
    return (
      <form className="ps-pay-form" onSubmit={submit}>
        <p className="ps-pay-sub">{t.booking.pay.bank.sub}</p>
        <dl className="ps-bank">
          <div><dt>{t.booking.pay.bank.bank}</dt><dd>BBVA México</dd></div>
          <div><dt>{t.booking.pay.bank.holder}</dt><dd>Alejandra Palomo</dd></div>
          <div><dt>{t.booking.pay.bank.clabe}</dt><dd>012 180 00000000 0000</dd></div>
          <div><dt>{t.booking.pay.bank.ref}</dt><dd>—</dd></div>
        </dl>
        <button type="submit" className="ps-btn ps-btn-primary ps-btn-wide">{t.booking.pay.bank.submit}</button>
      </form>
    );
  }
  if (method === "cash") {
    return (
      <form className="ps-pay-form" onSubmit={submit}>
        <p className="ps-pay-sub">{t.booking.pay.cash.sub}</p>
        <button type="submit" className="ps-btn ps-btn-primary ps-btn-wide">{t.booking.pay.cash.submit}</button>
      </form>
    );
  }
  return null;
}

function PayPanel({ t, service, onConfirm }) {
  const [method, setMethod] = bUseState("card");
  const isInPerson = service && service.id.endsWith("inperson");
  const methods = [
    { id: "card", label: t.booking.pay.methods.card },
    { id: "paypal", label: t.booking.pay.methods.paypal },
    { id: "bank", label: t.booking.pay.methods.bank },
    ...(isInPerson ? [{ id: "cash", label: t.booking.pay.methods.cash }] : []),
  ];
  return (
    <div className="ps-pay">
      <div className="ps-pay-tabs">
        {methods.map((m) => (
          <button
            key={m.id}
            type="button"
            className={"ps-pay-tab" + (method === m.id ? " ps-pay-tab-active" : "")}
            onClick={() => setMethod(m.id)}
          >{m.label}</button>
        ))}
      </div>
      <PayForm t={t} method={method} onConfirm={() => onConfirm({ method })} />
    </div>
  );
}

function CodePanel({ t, onConfirm }) {
  const [code, setCode] = bUseState("");
  const [err, setErr] = bUseState(false);
  const submit = (e) => {
    e.preventDefault();
    if (VALID_CODES.includes(code.trim().toUpperCase())) {
      setErr(false);
      onConfirm({ method: "code", code: code.trim().toUpperCase() });
    } else {
      setErr(true);
    }
  };
  return (
    <form className="ps-pay ps-code" onSubmit={submit}>
      <p className="ps-pay-sub">{t.booking.code.sub}</p>
      <label className="ps-field ps-field-full">
        <span>{t.booking.code.title}</span>
        <input
          type="text"
          value={code}
          onChange={(e) => { setCode(e.target.value); setErr(false); }}
          placeholder={t.booking.code.placeholder}
          maxLength="12"
          autoCapitalize="characters"
          className="ps-code-input"
          required
        />
      </label>
      {err && <div className="ps-code-err">{t.booking.code.invalid}</div>}
      <button type="submit" className="ps-btn ps-btn-primary ps-btn-wide">{t.booking.code.submit}</button>
    </form>
  );
}

// ── Summary sidebar ─────────────────────────────────────────────────────────

function BookingSummary({ t, lang, service, date, slot, onChange }) {
  return (
    <aside className="ps-summary">
      <div className="ps-summary-title">{t.booking.summary.title}</div>
      <dl className="ps-summary-list">
        <div>
          <dt>{t.booking.summary.service}</dt>
          <dd>{service ? service.name : "—"}</dd>
        </div>
        <div>
          <dt>{t.booking.summary.date}</dt>
          <dd>{date ? formatLongDate(date, lang, t) : "—"}</dd>
        </div>
        <div>
          <dt>{t.booking.summary.time}</dt>
          <dd>{slot || "—"}</dd>
        </div>
        <div className="ps-summary-total">
          <dt>{t.booking.summary.price}</dt>
          <dd>
            {service
              ? (lang === "en"
                  ? `$${service.price} ${t.misc.usd}`
                  : `$${service.price.toLocaleString("es-MX")} ${t.misc.mxn}`)
              : "—"}
          </dd>
        </div>
      </dl>
      {onChange && (
        <button type="button" className="ps-btn ps-btn-ghost ps-btn-sm" onClick={onChange}>
          {t.booking.summary.change}
        </button>
      )}
    </aside>
  );
}

// ── Confirmed ───────────────────────────────────────────────────────────────

function Confirmed({ t, lang, service, date, slot, method, onReset }) {
  const how = method === "code" ? t.booking.confirmed.held : t.booking.confirmed.paid;
  return (
    <div className="ps-confirmed">
      <div className="ps-confirmed-check" aria-hidden="true">
        <svg viewBox="0 0 32 32" width="32" height="32">
          <circle cx="16" cy="16" r="15" fill="none" stroke="currentColor" strokeWidth="1.2" />
          <path d="M10 16.5 14.5 21 22 12" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </div>
      <h3 className="ps-h2"><LocalMarkerText text={t.booking.confirmed.title} /></h3>
      <p className="ps-p">{t.booking.confirmed.sub}</p>
      <dl className="ps-confirmed-grid">
        <div>
          <dt>{t.booking.confirmed.when}</dt>
          <dd>{formatLongDate(date, lang, t)} · {slot}</dd>
        </div>
        <div>
          <dt>{t.booking.confirmed.what}</dt>
          <dd>{service.name}</dd>
        </div>
        <div>
          <dt>{t.booking.confirmed.how}</dt>
          <dd>{how}</dd>
        </div>
      </dl>
      <button type="button" className="ps-btn ps-btn-ghost" onClick={onReset}>{t.booking.confirmed.again}</button>
    </div>
  );
}

// ── Booking section ─────────────────────────────────────────────────────────

const Booking = bForwardRef(function Booking({ t, lang, primaryFlow, preselectService }, ref) {
  const [view, setView] = bUseState(() => {
    const d = new Date();
    d.setHours(0, 0, 0, 0);
    return startOfMonth(d);
  });
  const [date, setDate] = bUseState(null);
  const [slot, setSlot] = bUseState(null);
  const [serviceId, setServiceId] = bUseState(preselectService || "ind-remote");
  const [details, setDetails] = bUseState({ name: "", email: "", phone: "", note: "" });
  const [flow, setFlow] = bUseState(primaryFlow || "pay");
  const [confirmed, setConfirmed] = bUseState(null);

  // Reflect external preselect (service chip on /services).
  bUseEffect(() => {
    if (preselectService) setServiceId(preselectService);
  }, [preselectService]);

  // Reflect tweak-driven default flow until the user touches the chooser.
  const flowTouchedRef = React.useRef(false);
  bUseEffect(() => {
    if (!flowTouchedRef.current) setFlow(primaryFlow);
  }, [primaryFlow]);

  const service = t.services.items.find((s) => s.id === serviceId) || t.services.items[0];
  const canContinue = date && slot && details.name && details.email;

  if (confirmed) {
    return (
      <section className="ps-section ps-section-soft" id="book" ref={ref} data-screen-label="Booking confirmed">
        <div className="ps-section-head">
          <Eyebrow>{t.booking.eyebrow}</Eyebrow>
        </div>
        <Confirmed
          t={t} lang={lang}
          service={service}
          date={confirmed.date}
          slot={confirmed.slot}
          method={confirmed.method}
          onReset={() => {
            setConfirmed(null);
            setDate(null);
            setSlot(null);
          }}
        />
      </section>
    );
  }

  return (
    <section className="ps-section ps-section-soft" id="book" ref={ref} data-screen-label="Booking">
      <div className="ps-section-head">
        <Eyebrow>{t.booking.eyebrow}</Eyebrow>
        <SectionTitle>{t.booking.title}</SectionTitle>
        <p className="ps-section-note">{t.booking.subtitle}</p>
      </div>

      <ServicePicker t={t} lang={lang} value={serviceId} onChange={setServiceId} />

      <div className="ps-booking-grid">
        <div className="ps-booking-main">
          <div className="ps-booking-cols">
            <div className="ps-booking-col">
              <div className="ps-step-label">{t.booking.step.date}</div>
              <MonthCalendar
                t={t} lang={lang}
                view={view} setView={setView}
                selected={date} setSelected={(d) => { setDate(d); setSlot(null); }}
              />
            </div>
            <div className="ps-booking-col">
              <div className="ps-step-label">{t.booking.step.time}</div>
              <SlotPicker t={t} selectedDate={date} slot={slot} setSlot={setSlot} />
            </div>
          </div>

          {date && slot && (
            <div className="ps-booking-revealed">
              <div className="ps-step-divider" />
              <div className="ps-step-label">{t.booking.step.details}</div>
              <DetailsForm t={t} value={details} onChange={setDetails} />

              <div className="ps-step-divider" />
              <div className="ps-step-label">{t.booking.step.confirm}</div>
              <FlowChooser
                t={t}
                value={flow}
                onChange={(v) => { flowTouchedRef.current = true; setFlow(v); }}
              />

              {canContinue && flow === "pay" && (
                <PayPanel
                  t={t}
                  service={service}
                  onConfirm={(res) => setConfirmed({ date, slot, method: res.method })}
                />
              )}
              {canContinue && flow === "code" && (
                <CodePanel
                  t={t}
                  onConfirm={(res) => setConfirmed({ date, slot, method: res.method })}
                />
              )}
            </div>
          )}
        </div>

        <BookingSummary t={t} lang={lang} service={service} date={date} slot={slot} />
      </div>
    </section>
  );
});

window.Booking = Booking;
