/* ============================================================
   BY ANY MEANS GTA · Free Trial funnel
   Three steps: form -> calendar -> confirmation.
   Shared chrome (Footer, SocialIcon, useReveal, submitLead) from
   gta/shared.jsx. Calendar availability is LIVE: fetched from the
   portal availability API (which reads the GHL booking calendar for
   the player's age group), and confirming books the real slot.
   ============================================================ */
const { useState, useEffect, useRef } = React;

const FT_EMAIL = 'info@byanymeanstoronto.ca';
const FT_PHONE_DISPLAY = '(289) 816-6569';
const FT_PHONE_HREF = 'tel:+12898166569';

// GHL booking calendars per group (entry points in the portal).
// Age decides the group: 13 and under train with Group 1, 14+ with Group 2.
const FT_CALENDARS = {
  elementary: 'Cmw4bCVBhexgi0Oi0Dkf',  // Group 1 (Elementary School)
  high: 'G5y4QI0MsFq3159IhFU7',        // Group 2 (High School)
};
function ftGroupForAge(age) { return Number(age) >= 14 ? 'high' : 'elementary'; }
function ftGroupLabel(age) { return Number(age) >= 14 ? 'High School group' : 'Elementary group'; }
function ftAgeOk(v) { const n = Number(v); return Number.isFinite(n) && n >= 5 && n <= 19; }
const FT_AVAIL_URL = 'https://portal.byanymeansbusiness.com/api/website/availability';

/* ---------- date + slot helpers ---------- */
function ftAddDays(d, n) { const x = new Date(d); x.setDate(x.getDate() + n); return x; }
function ftISO(d) { return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0'); }
function ftDow(d) { return d.toLocaleDateString('en-US', { weekday: 'short' }); }
function ftMo(d) { return d.toLocaleDateString('en-US', { month: 'short' }); }
function ftLong(d) { return d.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' }); }
function ftSameDay(a, b) { return a && b && ftISO(a) === ftISO(b); }
function ftSlotTime(iso) { return new Date(iso).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); }

// avail = { 'YYYY-MM-DD': [slotISO, ...] } from the availability API
function ftSlotsFor(avail, d) {
  return ((avail && avail[ftISO(d)]) || []).map((iso) => ({ iso, time: ftSlotTime(iso) }));
}
function ftOpenCount(avail, d) { return ((avail && avail[ftISO(d)]) || []).length; }

const FT_TODAY = new Date();

/* ============================================================
   HEADER
   ============================================================ */
function FtHeader() {
  return (
    <header className="ft-head">
      <div className="container-wide ft-head__in">
        <a className="ft-head__logo" href="index.html">
          <span className="ft-head__mark" />
          <span className="ft-head__word">By Any Means <b>GTA</b></span>
        </a>
        <div className="ft-head__right">
          <a className="ft-head__contact ft-head__contact--email" href={'mailto:' + FT_EMAIL}>{FT_EMAIL}</a>
          <a className="ft-head__contact ft-head__phone" href={FT_PHONE_HREF}>{FT_PHONE_DISPLAY}</a>
        </div>
      </div>
    </header>
  );
}

/* ============================================================
   PROGRESS
   ============================================================ */
const FT_STEPS = ['Your details', 'Pick a time', 'Confirmed'];
function FtProgress({ index }) {
  return (
    <div className="ft-prog">
      {FT_STEPS.map((label, i) => (
        <React.Fragment key={label}>
          {i > 0 && <span className={'ft-prog__line' + (i <= index ? ' is-done' : '')} />}
          <div className={'ft-prog__step' + (i === index ? ' is-active' : i < index ? ' is-done' : '')}>
            <span className="ft-prog__dot">{i < index ? '\u2713' : i + 1}</span>
            <span className="ft-prog__label">{label}</span>
          </div>
        </React.Fragment>
      ))}
    </div>
  );
}

/* ============================================================
   STEP 1 — FORM
   ============================================================ */
const FT_START = ['Immediately', 'Within 2 weeks', 'Within 2 months'];
const FT_ORDER = ['pFirst', 'pLast', 'aFirst', 'aLast', 'age', 'email', 'phone', 'nearOakville', 'startWhen'];
function ftCompleteMap(f) {
  return {
    pFirst: !!f.pFirst.trim(), pLast: !!f.pLast.trim(),
    aFirst: !!f.aFirst.trim(), aLast: !!f.aLast.trim(),
    age: ftAgeOk(f.age),
    email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(f.email.trim()),
    phone: f.phone.replace(/\D/g, '').length >= 10,
    nearOakville: !!f.nearOakville, startWhen: !!f.startWhen,
  };
}
function ftNextKey(f) { const cm = ftCompleteMap(f); return FT_ORDER.find((k) => !cm[k]) || null; }

function FtForm({ form, setForm, onSubmit }) {
  const [showErr, setShowErr] = useState(false);
  const [glowKey, setGlowKey] = useState(null);
  const formRef = useRef(form); formRef.current = form;
  const focusedRef = useRef(null);
  const glowTimer = useRef(null);

  // After any change, wait 3s then glow the next incomplete field — unless the
  // user has moved into that field themselves (then no glow). Typing reschedules.
  const scheduleGlow = () => {
    clearTimeout(glowTimer.current);
    setGlowKey(null);
    glowTimer.current = setTimeout(() => {
      const nk = ftNextKey(formRef.current);
      if (nk && focusedRef.current !== nk) setGlowKey(nk);
    }, 3000);
  };
  useEffect(() => () => clearTimeout(glowTimer.current), []);

  const set = (k) => (e) => { setForm((f) => ({ ...f, [k]: e.target.value })); scheduleGlow(); };
  const pick = (k, v) => { setForm((f) => ({ ...f, [k]: v })); scheduleGlow(); };
  const onFocusField = (k) => { focusedRef.current = k; if (glowKey === k) setGlowKey(null); };
  const onBlurField = () => { focusedRef.current = null; };
  const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim());
  const phoneOk = form.phone.replace(/\D/g, '').length >= 10;

  const completeMap = {
    pFirst: !!form.pFirst.trim(), pLast: !!form.pLast.trim(),
    aFirst: !!form.aFirst.trim(), aLast: !!form.aLast.trim(),
    age: ftAgeOk(form.age),
    email: emailOk, phone: phoneOk,
    nearOakville: !!form.nearOakville, startWhen: !!form.startWhen,
  };
  const order = FT_ORDER;
  const total = order.length;
  const done = order.filter((k) => completeMap[k]).length;
  const valid = done === total;

  const submit = (e) => { e.preventDefault(); setShowErr(true); if (valid) onSubmit(); };
  const errC = (cond) => (showErr && cond ? ' is-error' : '');
  const glowC = (k) => (k === glowKey ? ' is-glow' : '');
  const fp = (k) => ({ onFocus: () => onFocusField(k), onBlur: onBlurField });

  return (
    <form className="ft-form" onSubmit={submit} noValidate>
      <div className="ft-form__main">
        <div className="ft-rail" aria-hidden="true">
          <div className="ft-rail__track"><div className="ft-rail__fill" style={{ height: (done / total * 100) + '%' }} /></div>
          <div className="ft-rail__count">{done}/{total}</div>
        </div>
        <div className="ft-form__fields">
          <div className="ft-row">
            <div className={'ft-field' + glowC('pFirst')}>
              <label className="ft-field__label" htmlFor="pFirst">Parent first name</label>
              <input id="pFirst" className={errC(!form.pFirst.trim())} type="text" placeholder="First" value={form.pFirst} onChange={set('pFirst')} {...fp('pFirst')} />
            </div>
            <div className={'ft-field' + glowC('pLast')}>
              <label className="ft-field__label" htmlFor="pLast">Parent last name</label>
              <input id="pLast" className={errC(!form.pLast.trim())} type="text" placeholder="Last" value={form.pLast} onChange={set('pLast')} {...fp('pLast')} />
            </div>
          </div>
          <div className="ft-row">
            <div className={'ft-field' + glowC('aFirst')}>
              <label className="ft-field__label" htmlFor="aFirst">Player first name</label>
              <input id="aFirst" className={errC(!form.aFirst.trim())} type="text" placeholder="First" value={form.aFirst} onChange={set('aFirst')} {...fp('aFirst')} />
            </div>
            <div className={'ft-field' + glowC('aLast')}>
              <label className="ft-field__label" htmlFor="aLast">Player last name</label>
              <input id="aLast" className={errC(!form.aLast.trim())} type="text" placeholder="Last" value={form.aLast} onChange={set('aLast')} {...fp('aLast')} />
            </div>
          </div>
          <div className={'ft-field' + glowC('age')}>
            <label className="ft-field__label" htmlFor="age">How old is your player?</label>
            <input id="age" className={errC(!ftAgeOk(form.age))} type="number" min="5" max="19" inputMode="numeric" placeholder="Age" value={form.age} onChange={set('age')} {...fp('age')} style={{ maxWidth: '120px' }} />
          </div>
          <div className={'ft-field' + glowC('email')}>
            <label className="ft-field__label" htmlFor="email">Parent email</label>
            <input id="email" className={errC(!emailOk)} type="email" placeholder="you@email.com" value={form.email} onChange={set('email')} {...fp('email')} />
          </div>
          <div className={'ft-field' + glowC('phone')}>
            <label className="ft-field__label" htmlFor="phone">Parent phone</label>
            <input id="phone" className={errC(!phoneOk)} type="tel" placeholder="(289) 000-0000" value={form.phone} onChange={set('phone')} {...fp('phone')} />
          </div>
          <div className={'ft-field' + glowC('nearOakville')}>
            <label className="ft-field__label">Are you close to Oakville?</label>
            <div className="ft-seg ft-seg--2">
              {['Yes', 'No'].map((o) => (
                <button type="button" key={o} className={'ft-seg__btn' + (form.nearOakville === o ? ' is-on' : '')} onClick={() => pick('nearOakville', o)} {...fp('nearOakville')}>{o}</button>
              ))}
            </div>
          </div>
          <div className={'ft-field' + glowC('startWhen')}>
            <label className="ft-field__label">When would you like to start training?</label>
            <div className="ft-seg ft-seg--3">
              {FT_START.map((o) => (
                <button type="button" key={o} className={'ft-seg__btn' + (form.startWhen === o ? ' is-on' : '')} onClick={() => pick('startWhen', o)} {...fp('startWhen')}>{o}</button>
              ))}
            </div>
          </div>
        </div>
      </div>
      <button className="btn btn--primary btn--lg ft-submit" type="submit">See available times <span className="btn__arrow">&rarr;</span></button>
      <div className="ft-trust">100% free. No commitment. Spots are limited.</div>
    </form>
  );
}

/* ============================================================
   STEP 2 — CALENDAR
   ============================================================ */
function FtMonth({ selectedISO, onPick }) {
  const [view, setView] = useState(new Date(FT_TODAY.getFullYear(), FT_TODAY.getMonth(), 1));
  const y = view.getFullYear(), m = view.getMonth();
  const first = new Date(y, m, 1);
  const startPad = first.getDay();
  const daysInMonth = new Date(y, m + 1, 0).getDate();
  const todayMid = new Date(FT_TODAY.getFullYear(), FT_TODAY.getMonth(), FT_TODAY.getDate());
  const canPrev = !(y === FT_TODAY.getFullYear() && m === FT_TODAY.getMonth());
  const cells = [];
  for (let i = 0; i < startPad; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(y, m, d));
  return (
    <div className="ft-month">
      <div className="ft-month__nav">
        <button className="ft-month__arrow" disabled={!canPrev} onClick={() => setView(new Date(y, m - 1, 1))} aria-label="Previous month">&larr;</button>
        <div className="ft-month__title">{view.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}</div>
        <button className="ft-month__arrow" onClick={() => setView(new Date(y, m + 1, 1))} aria-label="Next month">&rarr;</button>
      </div>
      <div className="ft-month__grid">
        {['S', 'M', 'T', 'W', 'T', 'F', 'S'].map((d, i) => <div className="ft-month__dow" key={i}>{d}</div>)}
        {cells.map((d, i) => {
          if (!d) return <div className="ft-month__cell ft-month__cell--empty" key={'e' + i} />;
          const past = d < todayMid;
          const on = selectedISO === ftISO(d);
          return (
            <button key={ftISO(d)} className={'ft-month__cell' + (on ? ' is-on' : '')} disabled={past} onClick={() => onPick(d)}>{d.getDate()}</button>
          );
        })}
      </div>
    </div>
  );
}

function FtCalendar({ booking, setBooking, onBack, onConfirm, sending, sendErr, avail, availErr, onRetryAvail }) {
  const [showMonth, setShowMonth] = useState(false);
  // Shows the "pick a time" prompt + highlights the slots when someone taps
  // Confirm before choosing a time.
  const [needTime, setNeedTime] = useState(false);
  // First 4 dates that actually have open slots; fall back to the next 4 days.
  const availDays = avail ? Object.keys(avail).filter((k) => avail[k].length).sort().slice(0, 4).map((k) => new Date(k + 'T00:00:00')) : [];
  const days = availDays.length ? availDays : [0, 1, 2, 3].map((i) => ftAddDays(FT_TODAY, i));
  const selected = booking.dateISO ? new Date(booking.dateISO + 'T00:00:00') : null;
  const slots = selected ? ftSlotsFor(avail, selected) : [];
  const pickDate = (d) => setBooking((b) => ({ ...b, dateISO: ftISO(d), time: null, iso: null }));
  const pickTime = (s) => { setBooking((b) => ({ ...b, time: s.time, iso: s.iso })); setNeedTime(false); };
  const ready = booking.dateISO && booking.iso;
  // Confirm is always tappable; if no time is picked yet, prompt instead of
  // silently doing nothing.
  const handleConfirm = () => {
    if (!ready) {
      setNeedTime(true);
      requestAnimationFrame(() => {
        const el = document.querySelector(booking.dateISO ? '.ft-slots' : '.ft-days');
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
      });
      return;
    }
    onConfirm();
  };

  if (availErr) return (
    <div>
      <p className="ft-slots__empty">We couldn't load available times right now.</p>
      <div className="ft-cal__actions">
        <button className="ft-back" onClick={onBack}>&larr; Back</button>
        <button className="btn btn--primary btn--lg" onClick={onRetryAvail}>Try again</button>
      </div>
    </div>
  );
  if (!avail) return <p className="ft-slots__empty">Loading available times\u2026</p>;

  return (
    <div>
      <div className="ft-days">
        {days.map((d) => {
          const on = ftSameDay(selected, d);
          return (
            <button key={ftISO(d)} className={'ft-day' + (on ? ' is-on' : '')} onClick={() => pickDate(d)}>
              <span className="ft-day__dow">{ftDow(d)}</span>
              <span className="ft-day__num">{d.getDate()}</span>
              <span className="ft-day__mo">{ftMo(d)}</span>
            </button>
          );
        })}
      </div>

      <button className="ft-monthtoggle" onClick={() => setShowMonth((v) => !v)}>
        {showMonth ? '\u2191 Hide full calendar' : '\u2193 View full month'}
      </button>
      {showMonth && <FtMonth selectedISO={booking.dateISO} onPick={pickDate} />}

      {selected && (
        <div className={'ft-slots' + (needTime && !booking.iso ? ' is-need' : '')}>
          <div className="ft-slots__head">Times for {ftLong(selected)}</div>
          {slots.length ? (
            <>
              <p className="ft-slots__hint">Tap a time to select it, then confirm below.</p>
              <div className="ft-slots__grid">
                {slots.map((s) => (
                  <button key={s.iso} type="button" className={'ft-slot' + (booking.iso === s.iso ? ' is-on' : '')} onClick={() => pickTime(s)}>{s.time}</button>
                ))}
              </div>
            </>
          ) : <p className="ft-slots__empty">No sessions on this day. Try another date.</p>}
        </div>
      )}

      <div className="ft-cal__foot">
        {ready && (
          <div className="ft-cal__summary">Selected: <b>{ftLong(selected)} at {booking.time}</b></div>
        )}
        {needTime && !ready && (
          <p className="ft-cal__needtime" role="alert">{booking.dateISO ? 'Please pick a time above to confirm your spot.' : 'Please pick a day and time above to confirm your spot.'}</p>
        )}
        {sendErr && <p className="ft-slots__empty" role="alert" style={{ color: '#e07070' }}>{sendErr}</p>}
        <div className="ft-cal__actions">
          <button className="ft-back" onClick={onBack}>&larr; Back</button>
          <button className="btn btn--primary btn--lg ft-cal__confirm" disabled={sending} onClick={handleConfirm}>{sending ? 'Confirming…' : <>Confirm my spot <span className="btn__arrow">&rarr;</span></>}</button>
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   TRUST SECTIONS
   ============================================================ */
const FT_EXPECT = [
  ['A real session on the floor', 'Your player trains alongside our athletes in a live session, not a watered-down sample. Real reps, real coaching, from minute one.'],
  ['The modern method, live', 'See our Constraints-Led Approach in action, the science-backed way we build decision-makers instead of drill-runners.'],
  ['Meet the family', 'Talk to the coaches, feel the culture, and ask anything. By the end you will know if this is the right home for your player.'],
];
function FtExpect() {
  const ref = useReveal();
  return (
    <section className="ft-sec ft-sec--deep" ref={ref}>
      <div className="container">
        <div className="ft-sec__head reveal">
          <div className="ft-sec__eyebrow eyebrow eyebrow--rule">What to expect</div>
          <h2 className="ft-sec__title">One session. <em>Zero pressure.</em></h2>
          <p className="ft-sec__sub">Your free trial is built to show you exactly how we develop players. Come see it for yourself.</p>
        </div>
        <div className="ft-expect reveal">
          {FT_EXPECT.map(([t, d], i) => (
            <div className="ft-expect__card" key={t}>
              <div className="ft-expect__num">{String(i + 1).padStart(2, '0')}</div>
              <h3 className="ft-expect__t">{t}</h3>
              <p className="ft-expect__d">{d}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

const FT_TST = [
  ['My son has grown so much in just a few months, not just as a player but in confidence. The coaches actually care about who these kids become.', 'Marcus T.', 'Jan 29, 2026'],
  ['The CLA approach is the real deal. He is reading the game better than ever and genuinely looks forward to every session.', 'Priya S.', 'Dec 07, 2025'],
  ['Best basketball decision we made. Real coaching, real community, and a culture that pushes our daughter to be her best.', 'Dwayne R.', 'Sep 02, 2025'],
];
function FtTestimonials() {
  const ref = useReveal();
  return (
    <section className="ft-sec" ref={ref}>
      <div className="container">
        <div className="ft-sec__head reveal">
          <div className="ft-sec__eyebrow eyebrow eyebrow--rule">Trusted by GTA families</div>
          <h2 className="ft-sec__title">What they're <em>saying.</em></h2>
        </div>
        <div className="ft-rating reveal">
          <div className="ft-rating__score">5.0</div>
          <div className="ft-rating__meta">
            <div className="ft-rating__stars">{'\u2605\u2605\u2605\u2605\u2605'}</div>
            <div className="ft-rating__label">Average across Google reviews</div>
          </div>
        </div>
        <div className="ft-tst reveal">
          {FT_TST.map(([body, name, date]) => (
            <div className="ft-tstcard" key={name}>
              <div className="ft-tstcard__top">
                <span className="ft-tstcard__stars">{'\u2605\u2605\u2605\u2605\u2605'}</span>
                <span className="ft-tstcard__date">{date}</span>
              </div>
              <p className="ft-tstcard__body">{body}</p>
              <div className="ft-tstcard__by">
                <span className="ft-tstcard__av">{name.split(' ').map((w) => w[0]).join('')}</span>
                <span>
                  <span className="ft-tstcard__name" style={{ display: 'block' }}>{name}</span>
                  <span className="ft-tstcard__src">Google review</span>
                </span>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

const FT_FAQ = [
  ['What is the purpose of the free trial?', 'The free trial is a chance for you, your player, and our coaching staff to see if our program is the right fit for their development and long-term growth. It is a no-pressure way to ask questions and understand exactly what we do and how we do it.'],
  ['What happens after the free trial?', 'If it feels like the right home, we will walk you through the membership options and help you choose the plan that fits your player. There is never any obligation to continue.'],
  ['How long will the free trial last?', 'Your trial is a full standard training session, so your player gets the complete experience, the same coaching and intensity our members get every week.'],
  ['Can parents stay and watch?', 'Absolutely. We encourage parents to stay, watch the session, and meet the coaches. Seeing the environment first-hand is part of what makes the decision easy.'],
  ['What should my player bring?', 'Just a basketball, athletic shoes, and water. Come ready to move, warm up, and have fun on the floor.'],
  ['Still have questions?', 'Reach out anytime at info@byanymeanstoronto.ca or give us a call. A coach is always happy to help before your first session.'],
];
function FtFaqItem({ q, a, open, onToggle }) {
  const innerRef = useRef(null);
  const [h, setH] = useState(0);
  useEffect(() => { setH(open && innerRef.current ? innerRef.current.scrollHeight : 0); }, [open]);
  return (
    <div className={'ft-faqitem' + (open ? ' is-open' : '')}>
      <button className="ft-faqitem__q" onClick={onToggle} aria-expanded={open}>
        <span className="ft-faqitem__qt">{q}</span>
        <span className="ft-faqitem__icon" aria-hidden="true" />
      </button>
      <div className="ft-faqitem__a" style={{ height: h }}>
        <div className="ft-faqitem__a-inner" ref={innerRef}><p>{a}</p></div>
      </div>
    </div>
  );
}
function FtFaq() {
  const ref = useReveal();
  const [open, setOpen] = useState(0);
  return (
    <section className="ft-sec ft-sec--deep" ref={ref}>
      <div className="container">
        <div className="ft-sec__head reveal">
          <div className="ft-sec__eyebrow eyebrow eyebrow--rule">Got questions</div>
          <h2 className="ft-sec__title">Before you <em>book.</em></h2>
        </div>
        <div className="ft-faq reveal">
          {FT_FAQ.map(([q, a], i) => (
            <FtFaqItem key={q} q={q} a={a} open={open === i} onToggle={() => setOpen(open === i ? -1 : i)} />
          ))}
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   STEP 3 — CONFIRMATION
   ============================================================ */
const FT_NEXT = [
  ['Check your email', 'Your trial details and confirmation are on the way to your inbox.'],
  ['Mark your calendar', 'Add your session date and time so it stays on your radar.'],
  ['Prepare for the session', 'Wear athletic gear, bring a basketball, and stay hydrated.'],
  ['Arrive early', 'Get there 10 to 15 minutes before to warm up and check in.'],
];
function FtConfirm({ form, booking, pending }) {
  const ref = useReveal();
  const [videoUrl, setVideoUrl] = useState(null);
  useEffect(() => {
    fetch(`https://portal.byanymeansbusiness.com/api/website/offer-media?client_id=${encodeURIComponent(window.LEADS_CLIENT_ID || '39875f07-0a4b-4429-a201-2249bc1f24df')}&offer_type=training`)
      .then((r) => r.json())
      .then((d) => { if (d && d.welcome_video) setVideoUrl(d.welcome_video); })
      .catch(() => {});
  }, []);
  const d = booking.dateISO ? new Date(booking.dateISO + 'T00:00:00') : null;
  return (
    <React.Fragment>
      <section className="ft-confirm" ref={ref}>
        <div className="ft-confirm__media" aria-hidden="true" />
        <div className="ft-confirm__overlay" aria-hidden="true" />
        <div className="container ft-confirm__inner reveal">
          <div className="ft-confirm__eyebrow eyebrow eyebrow--rule" style={{ justifyContent: 'center' }}>Thanks for booking</div>
          <h1 className="ft-confirm__title">{pending ? <>Request <em>received.</em></> : <>Your spot is <em>confirmed.</em></>}</h1>
          <p className="ft-confirm__sub">{pending
            ? <>Thanks{form.pFirst ? ', ' + form.pFirst : ''}. We received <strong>{form.aFirst || 'your player'}'s</strong> trial request and a coach will confirm the exact time by email shortly. Watch the quick welcome video below so you know exactly what to expect.</>
            : <>Thanks{form.pFirst ? ', ' + form.pFirst : ''}. We've saved <strong>{form.aFirst || 'your player'}'s</strong> place on the floor. Watch the quick welcome video below so you know exactly what to expect.</>}</p>
          <div className="ft-booking">
            <div className="ft-booking__item"><div className="ft-booking__k">Player</div><div className="ft-booking__v">{(form.aFirst || '') + ' ' + (form.aLast || '')}</div></div>
            <div className="ft-booking__item"><div className="ft-booking__k">Date</div><div className="ft-booking__v">{d ? d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) : 'TBD'}</div></div>
            <div className="ft-booking__item"><div className="ft-booking__k">Time</div><div className="ft-booking__v">{booking.time || 'TBD'}</div></div>
            <div className="ft-booking__item"><div className="ft-booking__k">Session</div><div className="ft-booking__v">Free Trial</div></div>
          </div>
        </div>
      </section>

      <div className="ft-video-wrap">
        {videoUrl ? (
          <div className="ft-video ft-video--live">
            <span className="ft-video__badge">Welcome video</span>
            <video className="ft-video__player" src={videoUrl} controls playsInline preload="metadata" />
          </div>
        ) : (
          <div className="ft-video">
            <div className="ft-video__grain" aria-hidden="true" />
            <span className="ft-video__badge">Welcome video</span>
            <button className="ft-video__play" aria-label="Play welcome video" />
            <div className="ft-video__label">Get ready for your first session</div>
            <div className="ft-video__cap">Video placeholder. The welcome video from your coach will play here.</div>
          </div>
        )}
      </div>

      <section className="ft-next">
        <div className="container">
          <div className="ft-sec__head reveal" style={{ marginBottom: 0 }}>
            <div className="ft-sec__eyebrow eyebrow eyebrow--rule">Next steps</div>
            <h2 className="ft-sec__title">Get ready to <em>hit the court.</em></h2>
          </div>
          <div className="ft-next__grid">
            {FT_NEXT.map(([t, dsc], i) => (
              <div className="ft-next__card" key={t}>
                <div className="ft-next__num">{String(i + 1).padStart(2, '0')}</div>
                <h3 className="ft-next__t">{t}</h3>
                <p className="ft-next__d">{dsc}</p>
              </div>
            ))}
          </div>
        </div>
      </section>
    </React.Fragment>
  );
}

/* ============================================================
   APP
   ============================================================ */
function App() {
  const [step, setStep] = useState('form'); // form | calendar | confirm
  const [form, setForm] = useState({ pFirst: '', pLast: '', aFirst: '', aLast: '', age: '', email: '', phone: '', nearOakville: null, startWhen: null });
  const [booking, setBooking] = useState({ dateISO: null, time: null, iso: null });
  const [sending, setSending] = useState(false);
  const [sendErr, setSendErr] = useState(null);
  const [avail, setAvail] = useState(null);     // { 'YYYY-MM-DD': [slotISO] }
  const [availErr, setAvailErr] = useState(false);
  const [pending, setPending] = useState(false); // lead saved but slot not booked

  useEffect(() => { window.scrollTo({ top: 0, behavior: 'smooth' }); }, [step]);

  const calendarId = ftAgeOk(form.age) ? FT_CALENDARS[ftGroupForAge(form.age)] : null;

  const loadAvail = async () => {
    if (!calendarId) return;
    setAvail(null);
    setAvailErr(false);
    try {
      const r = await fetch(`${FT_AVAIL_URL}?client_id=${encodeURIComponent(window.LEADS_CLIENT_ID || '39875f07-0a4b-4429-a201-2249bc1f24df')}&calendar=${encodeURIComponent(calendarId)}&days=31`);
      const data = await r.json();
      if (!r.ok) throw new Error(data.error || 'availability failed');
      setAvail(data.days || {});
    } catch (e) {
      setAvailErr(true);
    }
  };

  useEffect(() => { if (step === 'calendar') loadAvail(); }, [step, calendarId]);

  // Step 1 complete: capture the lead right away (lands at the form stage,
  // e.g. "interested", so follow-up automations can nudge non-bookers).
  // Fire-and-forget: never blocks the calendar from opening.
  const formLeadSent = useRef(false);
  const submitFormLead = () => {
    if (formLeadSent.current) return;
    formLeadSent.current = true;
    const athlete = `${form.aFirst} ${form.aLast}`.trim();
    submitLead({
      formType: 'free-trial',
      name: `${form.pFirst} ${form.pLast}`.trim(),
      email: form.email,
      phone: form.phone,
      fields: {
        step: 'form',
        message: `Free trial form filled for ${athlete} (age ${form.age}, ${ftGroupLabel(form.age)}). Picking a session time now. Wants to start: ${form.startWhen}. Near Oakville: ${form.nearOakville}.`,
        start_when_ghl: (form.startWhen || '').replace('Within', 'After'),
        athlete,
        athlete_first: form.aFirst.trim(),
        athlete_last: form.aLast.trim(),
        athlete_age: form.age,
        group: ftGroupLabel(form.age),
        start_when: form.startWhen,
        near_oakville: form.nearOakville,
      },
    }).catch(() => { formLeadSent.current = false; });
  };

  const confirmSpot = async () => {
    if (sending) return;
    setSending(true);
    setSendErr(null);
    const athlete = `${form.aFirst} ${form.aLast}`.trim();
    const when = booking.dateISO ? `${ftLong(new Date(booking.dateISO + 'T00:00:00'))} at ${booking.time}` : '';
    try {
      const result = await submitLead({
        formType: 'free-trial',
        name: `${form.pFirst} ${form.pLast}`.trim(),
        email: form.email,
        phone: form.phone,
        fields: {
          step: 'booking',
          message: `Free trial booking for ${athlete} (age ${form.age}, ${ftGroupLabel(form.age)}). Session: ${when}. Wants to start: ${form.startWhen}. Near Oakville: ${form.nearOakville}.`,
          start_when_ghl: (form.startWhen || '').replace('Within', 'After'),
          athlete,
          athlete_first: form.aFirst.trim(),
          athlete_last: form.aLast.trim(),
          athlete_age: form.age,
          group: ftGroupLabel(form.age),
          requested_date: booking.dateISO,
          requested_time: booking.time,
          booked_date: booking.dateISO,
          start_when: form.startWhen,
          near_oakville: form.nearOakville,
        },
        booking: { calendar_id: calendarId, start: booking.iso },
      });
      setPending(result.appointment !== 'booked');
      setStep('confirm');
    } catch (err) {
      setSendErr('Something went wrong booking your spot. Please try again, or email us at info@byanymeanstoronto.ca');
    } finally {
      setSending(false);
    }
  };

  const stepIndex = step === 'form' ? 0 : step === 'calendar' ? 1 : 2;

  if (step === 'confirm') {
    return (
      <React.Fragment>
        <FtHeader />
        <FtConfirm form={form} booking={booking} pending={pending} />
        <Footer />
      </React.Fragment>
    );
  }

  return (
    <React.Fragment>
      <FtHeader />
      <section className="ft-hero">
        <div className="ft-hero__media" aria-hidden="true" />
        <div className="ft-hero__grain" aria-hidden="true" />
        <div className="ft-hero__overlay" aria-hidden="true" />
        <div className="container-wide ft-hero__inner">
          <div className="ft-hero__copy">
            <div className="ft-hero__eyebrow eyebrow eyebrow--rule">Your first step starts here</div>
            <h1 className="ft-hero__title">Book your free <em>trial.</em></h1>
          </div>
          <div className="ft-hero__card-col">
            <div className="ft-card">
              <div className="ft-card__head">
                <h2 className="ft-card__title">{step === 'form' ? <>Claim your <em>free trial.</em></> : <>Pick your <em>time.</em></>}</h2>
                <p className="ft-card__note">{step === 'form' ? 'Tell us who is training. Takes under a minute.' : 'Choose a day and time. We will confirm by email.'}</p>
              </div>
              <div className="ft-card__body">
                {step === 'form'
                  ? <FtForm form={form} setForm={setForm} onSubmit={() => { submitFormLead(); setStep('calendar'); }} />
                  : <FtCalendar booking={booking} setBooking={setBooking} onBack={() => setStep('form')} onConfirm={confirmSpot} sending={sending} sendErr={sendErr} avail={avail} availErr={availErr} onRetryAvail={loadAvail} />}
              </div>
            </div>
          </div>
        </div>
      </section>

      <FtExpect />
      <FtTestimonials />
      <FtFaq />
      <Footer />
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
