/* TekConnected — booking widget (ported from briomarketing/Book.tsx)
   Pure React, no external libs. Talks to /api/cal/* for availability and bookings. */
(function () {
  const { useState, useEffect, useMemo, useRef } = React;

  /* ---------- Analytics stub (drop-in for @/lib/track) ---------- */
  const track = () => {};
  const Events = {
    BOOKING_OPENED: "booking_opened",
    BOOKING_TIME_PICKED: "booking_time_picked",
    BOOKING_DETAILS: "booking_details_done",
    BOOKING_QUESTIONS: "booking_questions_done",
    BOOKING_COMPLETE: "booking_complete",
    BOOKING_FAILED: "booking_failed",
  };

  const FALLBACK_TZ = "America/New_York";
  const DAYS_AHEAD = 14;
  const STORAGE_KEY = "tekconnected-booking-v1";

  const COUNTRY_CODES = [
    { code: "+1", label: "US / CA", flag: "🇺🇸" },
    { code: "+44", label: "United Kingdom", flag: "🇬🇧" },
    { code: "+61", label: "Australia", flag: "🇦🇺" },
    { code: "+64", label: "New Zealand", flag: "🇳🇿" },
    { code: "+353", label: "Ireland", flag: "🇮🇪" },
    { code: "+49", label: "Germany", flag: "🇩🇪" },
    { code: "+33", label: "France", flag: "🇫🇷" },
    { code: "+31", label: "Netherlands", flag: "🇳🇱" },
    { code: "+41", label: "Switzerland", flag: "🇨🇭" },
    { code: "+46", label: "Sweden", flag: "🇸🇪" },
    { code: "+47", label: "Norway", flag: "🇳🇴" },
    { code: "+45", label: "Denmark", flag: "🇩🇰" },
    { code: "+34", label: "Spain", flag: "🇪🇸" },
    { code: "+39", label: "Italy", flag: "🇮🇹" },
    { code: "+351", label: "Portugal", flag: "🇵🇹" },
    { code: "+65", label: "Singapore", flag: "🇸🇬" },
    { code: "+81", label: "Japan", flag: "🇯🇵" },
    { code: "+971", label: "UAE", flag: "🇦🇪" },
    { code: "+972", label: "Israel", flag: "🇮🇱" },
    { code: "+52", label: "Mexico", flag: "🇲🇽" },
    { code: "+55", label: "Brazil", flag: "🇧🇷" },
    { code: "+57", label: "Colombia", flag: "🇨🇴" },
    { code: "+91", label: "India", flag: "🇮🇳" },
    { code: "+27", label: "South Africa", flag: "🇿🇦" },
  ];

  function loadStoredBooking() {
    if (typeof window === "undefined") return null;
    try {
      const raw = window.localStorage.getItem(STORAGE_KEY);
      if (!raw) return null;
      const data = JSON.parse(raw);
      if (!data || !data.start || new Date(data.start).getTime() < Date.now()) {
        window.localStorage.removeItem(STORAGE_KEY);
        return null;
      }
      return data;
    } catch {
      return null;
    }
  }
  function saveStoredBooking(b) {
    if (typeof window === "undefined") return;
    try { window.localStorage.setItem(STORAGE_KEY, JSON.stringify(b)); } catch {}
  }
  function clearStoredBooking() {
    if (typeof window === "undefined") return;
    try { window.localStorage.removeItem(STORAGE_KEY); } catch {}
  }

  const STEPS = [
    { id: "time",      label: "Time" },
    { id: "details",   label: "Details" },
    { id: "questions", label: "Questions" },
    { id: "confirm",   label: "Confirm" },
  ];

  function ymd(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 buildDays() {
    const start = new Date();
    start.setHours(0, 0, 0, 0);
    return Array.from({ length: DAYS_AHEAD }, (_, i) => {
      const d = new Date(start);
      d.setDate(start.getDate() + i);
      return {
        iso: ymd(d),
        date: d,
        label: d.toLocaleDateString("en-US", { weekday: "short" }),
        num: d.getDate(),
        mon: d.toLocaleDateString("en-US", { month: "short" }),
      };
    });
  }
  function detectTz() {
    if (typeof Intl === "undefined") return FALLBACK_TZ;
    return Intl.DateTimeFormat().resolvedOptions().timeZone || FALLBACK_TZ;
  }
  const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  function hasResponse(v) {
    if (Array.isArray(v)) return v.length > 0;
    return typeof v === "string" && v.trim().length > 0;
  }

  /* ============================================================
     Main component
     ============================================================ */
  function Book() {
    const days = useMemo(buildDays, []);
    const [tz, setTz] = useState(FALLBACK_TZ);
    const [slotsByDate, setSlotsByDate] = useState({});
    const [status, setStatus] = useState("loading");
    const [error, setError] = useState(null);
    const [activeDay, setActiveDay] = useState(null);
    const [selectedSlot, setSelectedSlot] = useState(null);
    const [eventType, setEventType] = useState(null);

    const [step, setStep] = useState("time");
    const [name, setName] = useState("");
    const [email, setEmail] = useState("");
    const [phoneCC, setPhoneCC] = useState("+1");
    const [phoneNum, setPhoneNum] = useState("");
    const [responses, setResponses] = useState({});

    const phoneFull = phoneNum.trim()
      ? `${phoneCC}${phoneNum.replace(/\D/g, "").replace(/^0+/, "")}`
      : "";

    const [confirmed, setConfirmed] = useState(null);

    useEffect(() => {
      setTz(detectTz());
      const stored = loadStoredBooking();
      if (stored) {
        setConfirmed({ start: stored.start, meetingUrl: stored.meetingUrl });
        setStatus("success");
      }
    }, []);

    function resetWizard() {
      clearStoredBooking();
      setConfirmed(null);
      setStatus("ready");
      setError(null);
      setStep("time");
      setSelectedSlot(null);
      setName("");
      setEmail("");
      setPhoneCC("+1");
      setPhoneNum("");
      setResponses({});
    }

    useEffect(() => {
      let cancelled = false;
      (async () => {
        try {
          const res = await fetch("/api/cal/event-type");
          if (cancelled) return;
          if (!res.ok) return;
          const data = await res.json();
          setEventType(data);
        } catch {}
      })();
      return () => { cancelled = true; };
    }, []);

    useEffect(() => {
      let cancelled = false;
      (async () => {
        setStatus("loading");
        setError(null);
        const start = new Date();
        start.setHours(0, 0, 0, 0);
        const end = new Date(start);
        end.setDate(start.getDate() + DAYS_AHEAD);
        end.setHours(23, 59, 59, 999);

        try {
          const params = new URLSearchParams({
            start: start.toISOString(),
            end: end.toISOString(),
            timeZone: tz,
          });
          const res = await fetch(`/api/cal/slots?${params}`);
          if (cancelled) return;
          if (res.status === 503) {
            setStatus("error");
            setError("not-configured");
            return;
          }
          if (!res.ok) {
            const body = await res.json().catch(() => ({}));
            setStatus("error");
            setError(body.error || `Cal.com responded with ${res.status}`);
            return;
          }
          const data = await res.json();
          const slots = data.slots || {};
          setSlotsByDate(slots);
          const firstDayWithSlots = days.find((d) => (slots[d.iso] || []).length > 0);
          setActiveDay(firstDayWithSlots ? firstDayWithSlots.iso : days[0].iso);
          setStatus("ready");
        } catch (err) {
          if (cancelled) return;
          setStatus("error");
          setError(String(err));
        }
      })();
      return () => { cancelled = true; };
    }, [tz, days]);

    const phoneField = (eventType && eventType.fields)
      ? eventType.fields.find((f) => f.type === "phone") || null
      : null;
    const questionFields = useMemo(
      () => ((eventType && eventType.fields) || []).filter((f) => f.type !== "phone"),
      [eventType],
    );

    const activeSlots = activeDay ? slotsByDate[activeDay] || [] : [];
    const activeDayCell = days.find((d) => d.iso === activeDay) || null;

    function phoneError() {
      if (!(phoneField && phoneField.required) && !phoneNum.trim()) return null;
      const digits = phoneNum.replace(/\D/g, "");
      if (!digits) return "Phone number is required.";
      const ccDigits = phoneCC.replace(/\D/g, "");
      const total = ccDigits.length + digits.length;
      if (total < 10) return "Number too short — please include your full number.";
      if (total > 15) return "Number too long — please check and try again.";
      return null;
    }

    function canAdvance(s) {
      if (s === "time") return !!selectedSlot;
      if (s === "details") {
        if (!name.trim()) return false;
        if (!EMAIL_RE.test(email)) return false;
        if (phoneError() !== null) return false;
        return true;
      }
      if (s === "questions") {
        return questionFields.every((f) => !f.required || hasResponse(responses[f.slug]));
      }
      return true;
    }

    function goNext() {
      const idx = STEPS.findIndex((s) => s.id === step);
      if (idx < STEPS.length - 1) {
        const completing = STEPS[idx].id;
        if (completing === "time")      track(Events.BOOKING_TIME_PICKED, { slot: selectedSlot });
        if (completing === "details")   track(Events.BOOKING_DETAILS);
        if (completing === "questions") track(Events.BOOKING_QUESTIONS);
        setStep(STEPS[idx + 1].id);
      }
    }
    function goBack() {
      const idx = STEPS.findIndex((s) => s.id === step);
      if (idx > 0) setStep(STEPS[idx - 1].id);
    }

    async function submit(e) {
      e.preventDefault();
      if (step !== "confirm") {
        if (canAdvance(step)) goNext();
        return;
      }
      if (!selectedSlot || !name || !email) return;
      setStatus("submitting");
      setError(null);

      const payload = { start: selectedSlot, name, email, timeZone: tz, responses };
      if (phoneFull) payload.phone = phoneFull;

      try {
        const res = await fetch("/api/cal/book", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(payload),
        });
        const data = await res.json();
        if (!res.ok || !data.ok) {
          setStatus("ready");
          const raw = data.error || `Booking failed (${res.status})`;
          track(Events.BOOKING_FAILED, { reason: raw });
          if (/phone|invalid_number/i.test(raw)) {
            setError("That phone number doesn't look right — please double-check it and try again.");
          } else {
            setError(raw);
          }
          return;
        }
        saveStoredBooking({ start: selectedSlot, meetingUrl: data.meetingUrl, bookedAt: Date.now() });
        track(Events.BOOKING_COMPLETE, { slot: selectedSlot, name, email, timezone: tz, responses });
        setConfirmed({ start: selectedSlot, meetingUrl: data.meetingUrl });
        setStatus("success");
      } catch (err) {
        setStatus("ready");
        const msg = String(err);
        if (msg.includes("Failed to fetch") || msg.includes("NetworkError")) {
          setError("Network hiccup — your booking didn't send. Click Confirm again to retry.");
        } else {
          setError(msg);
        }
      }
    }

    const showWizardChrome =
      status !== "success" &&
      error !== "not-configured" &&
      !(status === "loading" && Object.keys(slotsByDate).length === 0);

    return (
      <div className="scheduler">
        <div className="scheduler__head">
          <div>
            <div className="scheduler__title">{(eventType && eventType.title) || "CRM Strategy Call"}</div>
            <div className="scheduler__sub">45 min · Zoom</div>
          </div>
          <div className="scheduler__pill">
            <span className="pulse-dot" />
            {status === "loading" ? "Loading availability…" : status === "success" ? "Booked" : "Live calendar"}
          </div>
        </div>

        {status === "success" && confirmed ? (
          <SuccessCard
            start={confirmed.start}
            timeZone={tz}
            meetingUrl={confirmed.meetingUrl}
            onBookAnother={resetWizard}
          />
        ) : error === "not-configured" ? (
          <NotConfigured />
        ) : (
          <>
            {showWizardChrome && <Stepper currentStep={step} />}

            <form onSubmit={submit} className="scheduler__panel">
              {step === "time" && (
                <TimeStep
                  days={days}
                  slotsByDate={slotsByDate}
                  activeDay={activeDay}
                  setActiveDay={(d) => { setActiveDay(d); setSelectedSlot(null); }}
                  activeSlots={activeSlots}
                  activeDayCell={activeDayCell}
                  selectedSlot={selectedSlot}
                  setSelectedSlot={setSelectedSlot}
                  tz={tz}
                  isLoading={status === "loading"}
                />
              )}
              {step === "details" && (
                <DetailsStep
                  name={name} setName={setName}
                  email={email} setEmail={setEmail}
                  phoneCC={phoneCC} setPhoneCC={setPhoneCC}
                  phoneNum={phoneNum} setPhoneNum={setPhoneNum}
                  phoneField={phoneField}
                  phoneErr={phoneNum.trim() ? phoneError() : null}
                />
              )}
              {step === "questions" && (
                <QuestionsStep fields={questionFields} responses={responses} setResponses={setResponses} />
              )}
              {step === "confirm" && (
                <ConfirmStep
                  selectedSlot={selectedSlot} tz={tz}
                  name={name} email={email} phone={phoneFull}
                  responses={responses} questionFields={questionFields}
                />
              )}

              {error && error !== "not-configured" && <div className="scheduler__error">{error}</div>}

              <WizardActions
                step={step}
                canAdvance={canAdvance(step)}
                submitting={status === "submitting"}
                onBack={goBack}
              />
            </form>

            <div className="scheduler__footer">
              <span>Powered by Cal.com</span>
              <span>SOC 2 · GDPR</span>
            </div>
          </>
        )}
      </div>
    );
  }

  /* ---------- Stepper ---------- */
  function Stepper({ currentStep }) {
    const currentIdx = STEPS.findIndex((s) => s.id === currentStep);
    return (
      <div className="scheduler__steps">
        {STEPS.map((s, i) => {
          const state = i < currentIdx ? "is-done" : i === currentIdx ? "is-active" : "";
          return (
            <div key={s.id} className={`scheduler__step ${state}`}>
              <span className="scheduler__step-n">{i < currentIdx ? "✓" : i + 1}</span>
              <span className="scheduler__step-l">{s.label}</span>
              {i < STEPS.length - 1 && <span className="scheduler__step-line" />}
            </div>
          );
        })}
      </div>
    );
  }

  /* ---------- Time step ---------- */
  function TimeStep({ days, slotsByDate, activeDay, setActiveDay, activeSlots, activeDayCell, selectedSlot, setSelectedSlot, tz, isLoading }) {
    return (
      <>
        <div className="scheduler__days">
          {days.map((d) => {
            const has = (slotsByDate[d.iso] || []).length > 0;
            const disabled = !isLoading && !has;
            return (
              <button
                type="button"
                key={d.iso}
                disabled={disabled}
                className={`scheduler__day ${d.iso === activeDay ? "is-active" : ""} ${disabled ? "is-disabled" : ""}`}
                onClick={() => setActiveDay(d.iso)}
              >
                <span className="scheduler__day-l">{d.label}</span>
                <span className="scheduler__day-n">{d.num}</span>
                <span className="scheduler__day-m">{d.mon}</span>
              </button>
            );
          })}
        </div>

        <div className="scheduler__times-head">
          <span>Available times</span>
          <span>
            {activeDayCell ? `${activeDayCell.label} ${activeDayCell.num} ${activeDayCell.mon}` : ""} · {tz}
          </span>
        </div>

        {isLoading && <div className="scheduler__loading">Loading availability…</div>}

        {!isLoading && activeSlots.length === 0 && (
          <div className="scheduler__empty">No slots open this day. Try another date above.</div>
        )}

        {activeSlots.length > 0 && (
          <div className="scheduler__times">
            {activeSlots.map((s) => {
              const isSelected = selectedSlot === s.time;
              const label = new Date(s.time).toLocaleTimeString("en-US", {
                hour: "numeric", minute: "2-digit", timeZone: tz,
              });
              return (
                <button
                  type="button"
                  key={s.time}
                  className={`scheduler__time ${isSelected ? "is-active" : ""}`}
                  onClick={() => setSelectedSlot(s.time)}
                >
                  {label}
                  {isSelected && <span className="scheduler__time-confirm">Selected</span>}
                </button>
              );
            })}
          </div>
        )}
      </>
    );
  }

  /* ---------- Country code dropdown ---------- */
  function CountrySelect({ value, onChange }) {
    const [open, setOpen] = useState(false);
    const ref = useRef(null);
    const optionRefs = useRef({});
    const searchBufferRef = useRef("");
    const searchTimerRef = useRef(null);

    const current = COUNTRY_CODES.find((c) => c.code === value) || COUNTRY_CODES[0];

    useEffect(() => {
      if (!open) return;
      const onDocMouseDown = (e) => {
        if (ref.current && !ref.current.contains(e.target)) setOpen(false);
      };
      const onDocKey = (e) => { if (e.key === "Escape") setOpen(false); };
      document.addEventListener("mousedown", onDocMouseDown);
      document.addEventListener("keydown", onDocKey);
      return () => {
        document.removeEventListener("mousedown", onDocMouseDown);
        document.removeEventListener("keydown", onDocKey);
      };
    }, [open]);

    useEffect(() => {
      return () => { if (searchTimerRef.current) clearTimeout(searchTimerRef.current); };
    }, []);

    function findMatch(query) {
      const q = query.toLowerCase();
      const qDigits = q.replace(/\D/g, "");
      return COUNTRY_CODES.find((c) => {
        if (c.label.toLowerCase().startsWith(q)) return true;
        if (qDigits && c.code.replace(/\D/g, "").startsWith(qDigits)) return true;
        return false;
      });
    }

    function onKeyDown(e) {
      if (!open) return;
      if (e.key === "ArrowDown" || e.key === "ArrowUp") {
        e.preventDefault();
        const items = COUNTRY_CODES.map((c) => optionRefs.current[c.code]).filter(Boolean);
        const focused = document.activeElement;
        let i = items.findIndex((el) => el === focused);
        if (i === -1) i = e.key === "ArrowDown" ? 0 : items.length - 1;
        else i = e.key === "ArrowDown" ? Math.min(items.length - 1, i + 1) : Math.max(0, i - 1);
        if (items[i]) { items[i].focus(); items[i].scrollIntoView({ block: "nearest" }); }
        return;
      }
      if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
        e.preventDefault();
        searchBufferRef.current += e.key;
        if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
        searchTimerRef.current = setTimeout(() => { searchBufferRef.current = ""; }, 700);
        const match = findMatch(searchBufferRef.current);
        if (match) {
          const btn = optionRefs.current[match.code];
          if (btn) { btn.focus(); btn.scrollIntoView({ block: "nearest" }); }
        }
      }
    }

    function handleOpen() {
      const next = !open;
      setOpen(next);
      if (next) {
        requestAnimationFrame(() => {
          if (optionRefs.current[value]) {
            optionRefs.current[value].focus();
            optionRefs.current[value].scrollIntoView({ block: "nearest" });
          }
        });
      }
    }

    return (
      <div className={`cc-select ${open ? "is-open" : ""}`} ref={ref} onKeyDown={onKeyDown}>
        <button type="button" className="cc-select__trigger" onClick={handleOpen} aria-haspopup="listbox" aria-expanded={open}>
          <span className="cc-select__flag" aria-hidden>{current.flag}</span>
          <span className="cc-select__code">{current.code}</span>
          <span className="cc-select__chev" aria-hidden>▾</span>
        </button>
        {open && (
          <div className="cc-select__menu" role="listbox">
            {COUNTRY_CODES.map((c) => {
              const isOn = c.code === value;
              return (
                <button
                  key={c.code}
                  ref={(el) => { optionRefs.current[c.code] = el; }}
                  type="button"
                  role="option"
                  aria-selected={isOn}
                  className={`cc-select__option ${isOn ? "is-on" : ""}`}
                  onClick={() => { onChange(c.code); setOpen(false); }}
                >
                  <span className="cc-select__flag" aria-hidden>{c.flag}</span>
                  <span className="cc-select__code">{c.code}</span>
                  <span className="cc-select__label">{c.label}</span>
                </button>
              );
            })}
          </div>
        )}
      </div>
    );
  }

  /* ---------- Details step ---------- */
  function DetailsStep({ name, setName, email, setEmail, phoneCC, setPhoneCC, phoneNum, setPhoneNum, phoneField, phoneErr }) {
    return (
      <div className="scheduler__form">
        <div className="scheduler__form-row">
          <label className="scheduler__field">
            <span>Full name</span>
            <input type="text" required value={name} onChange={(e) => setName(e.target.value)} placeholder="Your full name" />
          </label>
          <label className="scheduler__field">
            <span>Email</span>
            <input type="email" required value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@company.com" />
          </label>
        </div>
        {phoneField && (
          <div className="scheduler__field">
            <span>
              {phoneField.label}
              {!phoneField.required && <em className="scheduler__field-opt"> (optional)</em>}
            </span>
            <div className="scheduler__phone">
              <CountrySelect value={phoneCC} onChange={setPhoneCC} />
              <input
                type="tel" value={phoneNum}
                onChange={(e) => setPhoneNum(e.target.value)}
                placeholder="555 123 4567"
                required={phoneField.required}
                aria-label={phoneField.label}
              />
            </div>
            {phoneErr && <span className="scheduler__field-err">{phoneErr}</span>}
          </div>
        )}
      </div>
    );
  }

  /* ---------- Questions step ---------- */
  function QuestionsStep({ fields, responses, setResponses }) {
    if (fields.length === 0) {
      return <div className="scheduler__empty">No additional questions — go ahead and review your booking.</div>;
    }
    return (
      <div className="scheduler__form scheduler__form--questions">
        {fields.map((f) => (
          <FieldRow key={f.slug} field={f} value={responses[f.slug]} onChange={(v) => setResponses((r) => ({ ...r, [f.slug]: v }))} />
        ))}
      </div>
    );
  }

  function FieldRow({ field, value, onChange }) {
    const reqMark = field.required ? null : <em className="scheduler__field-opt"> (optional)</em>;

    if (field.type === "textarea") {
      return (
        <label className="scheduler__field">
          <span>{field.label}{reqMark}</span>
          <textarea
            required={field.required} rows={3}
            value={value || ""}
            onChange={(e) => onChange(e.target.value)}
            placeholder={field.placeholder}
          />
        </label>
      );
    }

    if (field.type === "multiselect" || field.type === "checkbox") {
      const arr = Array.isArray(value) ? value : [];
      const toggle = (opt) => {
        if (arr.includes(opt)) onChange(arr.filter((v) => v !== opt));
        else onChange([...arr, opt]);
      };
      return (
        <div className="scheduler__field">
          <span>{field.label}{reqMark}</span>
          <div className="scheduler__multiselect" role="group" aria-label={field.label}>
            {(field.options || []).map((opt) => {
              const isOn = arr.includes(opt);
              return (
                <label key={opt} className={`scheduler__multiselect-option ${isOn ? "is-on" : ""}`}>
                  <input type="checkbox" checked={isOn} onChange={() => toggle(opt)} />
                  <span>{opt}</span>
                </label>
              );
            })}
          </div>
        </div>
      );
    }

    if (field.type === "select" || field.type === "radio") {
      const current = value || "";
      return (
        <div className="scheduler__field">
          <span>{field.label}{reqMark}</span>
          <div className="scheduler__multiselect" role="radiogroup" aria-label={field.label}>
            {(field.options || []).map((opt) => {
              const isOn = current === opt;
              return (
                <label key={opt} className={`scheduler__multiselect-option ${isOn ? "is-on" : ""}`}>
                  <input type="radio" name={field.slug} checked={isOn} onChange={() => onChange(opt)} required={field.required} />
                  <span>{opt}</span>
                </label>
              );
            })}
          </div>
        </div>
      );
    }

    const inputType = field.type === "number" ? "number" : field.type === "phone" ? "tel" : field.type === "email" ? "email" : "text";
    return (
      <label className="scheduler__field">
        <span>{field.label}{reqMark}</span>
        <input
          type={inputType} required={field.required}
          value={value || ""}
          onChange={(e) => onChange(e.target.value)}
          placeholder={field.placeholder}
        />
      </label>
    );
  }

  /* ---------- Confirm step ---------- */
  function ConfirmStep({ selectedSlot, tz, name, email, phone, responses, questionFields }) {
    const date = selectedSlot ? new Date(selectedSlot) : null;
    const day = date && date.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", timeZone: tz });
    const time = date && date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", timeZone: tz });
    return (
      <div className="scheduler__summary">
        <div className="scheduler__summary-block">
          <div className="scheduler__summary-h">When</div>
          <div className="scheduler__summary-when">{day}, {time}</div>
          <div className="scheduler__summary-tz">{tz}</div>
        </div>
        <div className="scheduler__summary-block">
          <div className="scheduler__summary-h">Who</div>
          <div className="scheduler__summary-row">{name}</div>
          <div className="scheduler__summary-row scheduler__summary-row--mute">{email}</div>
          {phone && <div className="scheduler__summary-row scheduler__summary-row--mute">{phone}</div>}
        </div>
        {questionFields.length > 0 && (
          <div className="scheduler__summary-block">
            <div className="scheduler__summary-h">Pre-call answers</div>
            <div className="scheduler__summary-grid">
              {questionFields.map((f) => {
                const v = responses[f.slug];
                const display = Array.isArray(v) ? v.join(", ") : v || "—";
                return (
                  <div key={f.slug} className="scheduler__summary-qa">
                    <div className="scheduler__summary-q">{f.label}</div>
                    <div className="scheduler__summary-a">{display}</div>
                  </div>
                );
              })}
            </div>
          </div>
        )}
      </div>
    );
  }

  /* ---------- Wizard actions ---------- */
  function WizardActions({ step, canAdvance, submitting, onBack }) {
    const isFirst = step === STEPS[0].id;
    const isLast = step === STEPS[STEPS.length - 1].id;
    return (
      <div className="scheduler__actions">
        {!isFirst ? (
          <button type="button" className="scheduler__back" onClick={onBack} disabled={submitting}>← Back</button>
        ) : <span />}
        <button type="submit" className="scheduler__submit" disabled={submitting || !canAdvance}>
          {isLast ? (submitting ? "Booking…" : "Confirm booking →") : "Next →"}
        </button>
      </div>
    );
  }

  /* ---------- Success ---------- */
  function SuccessCard({ start, timeZone, meetingUrl, onBookAnother }) {
    const date = new Date(start);
    const day = date.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", timeZone });
    const time = date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", timeZone });
    return (
      <div className="scheduler__success">
        <div className="scheduler__success-icon">✓</div>
        <h3>You're booked.</h3>
        <p className="scheduler__success-when">
          {day} at {time}
          <br />
          <span>({timeZone})</span>
        </p>
        <p className="scheduler__success-note">
          Confirmation sent to your inbox with the calendar invite. We'll see you on the call.
        </p>
        <div className="scheduler__success-actions">
          {meetingUrl && (
            <a className="scheduler__success-link" href={meetingUrl} target="_blank" rel="noreferrer">
              Open meeting link →
            </a>
          )}
          <button type="button" className="scheduler__success-reset" onClick={onBookAnother}>Book another call</button>
        </div>
      </div>
    );
  }

  function NotConfigured() {
    return (
      <div style={{ padding: "40px 20px", color: "var(--ink-3)", fontFamily: "'JetBrains Mono', monospace", fontSize: 12, lineHeight: 1.6 }}>
        Cal.com isn't wired up yet. Set <code style={{ color: "var(--safety)" }}>CAL_API_KEY</code> and{" "}
        <code style={{ color: "var(--safety)" }}>CAL_EVENT_TYPE_ID</code> in Vercel env vars, then redeploy.
      </div>
    );
  }

  window.Book = Book;
})();
