/* ============================================================
   TEND, BRING TEND TO YOUR TEAM  (programme configurator)
   Toggle modules → a programme timeline assembles in real time,
   the Compass reflects the mix, and you start a conversation.
   ============================================================ */

/* Photograph from Unsplash, served from our own domain through /img/u.
   Credits and licence: design-source/photo-credits.md. Styles: .ph in site.css. */
function TPhoto({ id, alt, ratio = '4x3', pos, eager, sizes = '(min-width: 940px) 460px, 100vw', className = '' }) {
  const u = w => '/img/u/' + id + '?w=' + w + '&q=75&fm=webp&fit=crop';
  return (
    <figure className={'ph ph--' + ratio + (className ? ' ' + className : '')}>
      <img src={u(1200)} srcSet={[640, 960, 1400].map(w => u(w) + ' ' + w + 'w').join(', ')} sizes={sizes} alt={alt} loading={eager ? 'eager' : 'lazy'} fetchpriority={eager ? 'high' : undefined} decoding="async" style={pos ? { objectPosition: pos } : undefined} />
    </figure>
  );
}
const { useState: useJ, useMemo: useJM } = React;

const ANCHOR = { id: 'tend', name: 'TEND for each person', meta: 'Online · at their own pace', hours: 0.5, energy: 'aqua', glyph: 'compass', required: true,
  emphasis: { aqua: 20, coral: 16, amber: 14, violet: 16 }, note: 'Each person completes TEND. Every programme starts here.' };

const MODULES = [
  { id: 'keynote', name: 'TEND Keynote', meta: '60 minutes · stage', hours: 1, energy: 'coral', glyph: 'spark', group: 'TEND', emphasis: { coral: 28 }, note: 'Frame the room from the stage.' },
  { id: 'workshop4', name: 'TEND Workshop · 4h', meta: 'Half day · in person', hours: 4, energy: 'amber', glyph: 'engineer', group: 'TEND', emphasis: { amber: 26 }, note: 'A team working with TEND, hands on.' },
  { id: 'workshop8', name: 'TEND Workshop · 8h', meta: 'Full day · in person', hours: 8, energy: 'violet', glyph: 'champion', group: 'TEND', emphasis: { amber: 22, coral: 18 }, note: 'The full-day immersion.' },
  { id: 'team', name: 'Team Compass session', meta: '90 minutes', hours: 1.5, energy: 'aqua', glyph: 'compass', group: 'TEND', emphasis: { aqua: 18, violet: 14 }, note: 'The whole team on one Compass.' },
  { id: 'lab', name: 'TEND Leadership Lab', meta: '2 hours · team Compass and a 30-day plan', hours: 2, energy: 'aqua', glyph: 'reframe', group: 'TEND', emphasis: { aqua: 20, violet: 12 }, note: 'The team on one Compass, and a 30-day plan.' },
  { id: 'connection', name: 'The Neuroscience of Connection', meta: 'Facilitation · half day', hours: 4, energy: 'aqua', glyph: 'spark', group: 'Facilitation', emphasis: { aqua: 30, violet: 16 }, note: 'The relational base. Most accessible entry.' },
  { id: 'amygdala', name: 'The Amygdala in the Boardroom', meta: 'Facilitation · half day', hours: 4, energy: 'amber', glyph: 'engineer', group: 'Facilitation', emphasis: { amber: 28, coral: 14 }, note: 'Conditions where candour survives.' },
  { id: 'biological', name: 'Leadership Is a Biological Intervention', meta: 'Facilitation · half day', hours: 4, energy: 'coral', glyph: 'champion', group: 'Facilitation', emphasis: { coral: 30, violet: 16 }, note: 'The leader as the active agent.' },
  { id: 'psychopathy', name: 'The Neuroscience of Corporate Psychopathy', meta: 'Facilitation · half day', hours: 4, energy: 'violet', glyph: 'reframe', group: 'Facilitation', emphasis: { violet: 28, amber: 12 }, note: '' },
  { id: 'coaching', name: '1:1 coaching', meta: 'Ongoing · monthly', hours: 6, energy: 'violet', glyph: 'elevate', group: 'Support', emphasis: { violet: 20, aqua: 12 }, note: 'Individual support across the programme.' },
];

const GOALS = ['Self-awareness', 'Team alignment', 'Culture & safety', 'Navigating change'];
const AUDIENCES = ['One person', 'A team', 'A whole function', 'The executive board'];

function alertBox(form, msg) { let p = form.querySelector('.form-err'); if (!p) { p = document.createElement('p'); p.className = 'form-err caption'; p.setAttribute('role', 'alert'); form.appendChild(p); } p.textContent = msg || 'Something went wrong. Please try again.'; }

function classify(hours, selected) {
  const hasFac = selected.some(m => m.group === 'Facilitation');
  const count = selected.length;
  if (count === 0) return { type: 'TEND for each person', cadence: 'Online, at each person’s own pace', months: '·', bespoke: false };
  if (hasFac || count >= 3 || hours >= 12) return { type: 'Learning programme', cadence: '3 to 6 months · designed with you', months: '3–6', bespoke: true };
  if (count >= 1) return { type: 'Focused engagement', cadence: 'Over 2 to 6 weeks', months: 'under a month', bespoke: false };
  return { type: 'TEND for each person', cadence: 'Online', months: '·', bespoke: false };
}

function Journey() {
  window.useReveal();
  const [active, setActive] = useJ(() => {
    const a = {};
    (new URLSearchParams(location.search).get('add') || '').split(',').forEach(id => { if (MODULES.some(m => m.id === id)) a[id] = true; });
    return a;
  });
  React.useEffect(() => {
    if (!location.hash) return;
    const el = document.getElementById(location.hash.slice(1));
    if (el) requestAnimationFrame(() => window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 96 }));
  }, []);
  const [goal, setGoal] = useJ(GOALS[0]);
  const [audience, setAudience] = useJ(AUDIENCES[1]);
  const [sent, setSent] = useJ(false);

  const selected = MODULES.filter(m => active[m.id]);
  const allChosen = [ANCHOR, ...selected];
  const hours = allChosen.reduce((s, m) => s + m.hours, 0);
  const cls = classify(hours, selected);

  // compass emphasis from the mix
  const energy = useJM(() => {
    const base = { aqua: 18, coral: 18, amber: 18, violet: 18 };
    allChosen.forEach(m => { Object.entries(m.emphasis).forEach(([k, v]) => { base[k] += v; }); });
    return base;
  }, [active]);

  const { ref: compassRef, setTarget } = window.useAnimatedCompass(energy, { size: 240, style: 'field', idSeed: 'journey' });
  React.useEffect(() => { setTarget(energy); }, [energy, setTarget]);

  const toggle = (id) => setActive(a => ({ ...a, [id]: !a[id] }));

  return (
    <>
      <Nav active="journey" />
      <header className="section" style={{ paddingBottom: 'clamp(20px,3vw,36px)' }}>
        <div className="wrap">
          <div className="ph-hero">
            <div>
              <div className="eyebrow">Bring TEND to your team</div>
              <h1 className="display-xl" style={{ maxWidth: '15ch' }}>Shape a programme with us.</h1>
              <p className="lead" style={{ marginTop: 22, maxWidth: '56ch' }}>Start with TEND, add talks, workshops and facilitation topics, and see the shape of a programme for your team. When it looks right, send it to us and we will talk it through with you.</p>
            </div>
            <TPhoto id="photo-1759310610480-48649b55fbdf" ratio="4x3" eager pos="30% 50%" alt="Colleagues around a meeting table listen closely as one of them speaks" />
          </div>
        </div>
      </header>

      <section className="section" id="builder" style={{ paddingTop: 0 }}>
        <div className="wrap">
          <div className="journey-layout">
            {/* CONFIGURATOR */}
            <div className="journey-config">
              {/* intent */}
              <div className="jc-block">
                <div className="eyebrow no-rule">Your intent</div>
                <label className="jc-label">Primary goal</label>
                <div className="seg">
                  {GOALS.map(g => <button key={g} className={'seg-btn' + (goal === g ? ' on' : '')} onClick={() => setGoal(g)}>{g}</button>)}
                </div>
                <label className="jc-label" style={{ marginTop: 20 }}>Who is it for</label>
                <div className="seg">
                  {AUDIENCES.map(a => <button key={a} className={'seg-btn' + (audience === a ? ' on' : '')} onClick={() => setAudience(a)}>{a}</button>)}
                </div>
              </div>

              {/* anchor */}
              <div className="jc-block">
                <div className="eyebrow no-rule">The anchor</div>
                <div className="mod-card anchor on" style={{ '--energy-core': 'var(--aqua-core)', '--energy-deep': 'var(--aqua-deep)' }}>
                  <span className="mc-glyph"><Glyph name={ANCHOR.glyph} size={26} color="var(--aqua-deep)" /></span>
                  <div className="mc-text">
                    <div className="mc-name">{ANCHOR.name}</div>
                    <div className="mc-meta">{ANCHOR.meta} · {ANCHOR.note}</div>
                  </div>
                  <span className="mc-state locked">Included</span>
                </div>
              </div>

              {/* modules by group */}
              {['TEND', 'Facilitation', 'Support'].map(group => (
                <div className="jc-block" key={group}>
                  <div className="eyebrow no-rule">{group === 'TEND' ? 'Add TEND modules' : group === 'Facilitation' ? 'Add facilitation topics' : 'Add ongoing support'}</div>
                  <div className="mod-grid">
                    {MODULES.filter(m => m.group === group).map(m => (
                      <button key={m.id} className={'mod-card' + (active[m.id] ? ' on' : '')} onClick={() => toggle(m.id)}
                        style={{ '--energy-core': `var(--${m.energy}-core)`, '--energy-deep': `var(--${m.energy}-deep)` }}>
                        <span className="mc-glyph"><Glyph name={m.glyph} size={24} color={`var(--${m.energy}-deep)`} /></span>
                        <div className="mc-text">
                          <div className="mc-name">{m.name}</div>
                          <div className="mc-meta">{m.meta}</div>
                        </div>
                        <span className={'mc-toggle' + (active[m.id] ? ' on' : '')} aria-hidden="true">
                          {active[m.id] ? '✓' : '+'}
                        </span>
                      </button>
                    ))}
                  </div>
                </div>
              ))}
            </div>

            {/* LIVE SUMMARY */}
            <aside className="journey-summary">
              <div className="js-sticky">
                <div className="js-card">
                  <div className="js-head">
                    <div ref={compassRef} />
                    <div>
                      <div className="eyebrow no-rule" style={{ marginBottom: 6 }}>Your programme</div>
                      <div className="js-type">{cls.type}</div>
                      <div className="js-cadence">{cls.cadence}</div>
                    </div>
                  </div>

                  <div className="js-stats">
                    <div><div className="js-stat-v">{allChosen.length}</div><div className="js-stat-l">modules</div></div>
                    <div><div className="js-stat-v">{hours % 1 === 0 ? hours : hours.toFixed(1)}</div><div className="js-stat-l">contact hours</div></div>
                    <div><div className="js-stat-v">{cls.months === '3–6' ? '3 to 6' : cls.months}</div><div className="js-stat-l">{cls.months === 'under a month' ? 'to run' : 'months'}</div></div>
                  </div>

                  <div className="js-timeline">
                    {allChosen.map((m, i) => (
                      <div className="js-tl-item" key={m.id} style={{ '--energy-core': `var(--${m.energy}-core)`, animation: 'fadeUp var(--dur-base) var(--ease-out)' }}>
                        <span className="js-tl-dot" />
                        <div>
                          <div className="js-tl-name">{m.name}</div>
                          <div className="js-tl-meta">{m.meta}</div>
                        </div>
                      </div>
                    ))}
                  </div>

                  {cls.bespoke && (
                    <div className="js-bespoke"><Glyph name="reframe" size={18} color="var(--violet-deep)" /><span>Bespoke design factored in, sequenced to your cohort.</span></div>
                  )}

                  <a className="btn btn-ink btn-lg" href="#proposal" style={{ width: '100%', marginTop: 18 }}>Start a conversation<span className="btn-arrow">→</span></a>
                  <p className="caption" style={{ marginTop: 12, textAlign: 'center' }}>No obligation. We will talk it through with you first.</p>
                </div>
              </div>
            </aside>
          </div>
        </div>
      </section>

      {/* PROPOSAL FORM */}
      <section className="section section-sunk" id="proposal">
        <div className="wrap wrap-narrow">
          <div className="grid cols-2" style={{ alignItems: 'start', gap: 'clamp(28px,4vw,56px)' }}>
            <div>
              <div className="eyebrow">Start a conversation</div>
              <h2 className="display-m">Tell us the shape of it.</h2>
              <p className="body" style={{ marginTop: 16 }}>Send us your draft and we’ll come back to you, usually within two working days, to talk through timing and what your team needs.</p>
              <div className="js-recap card card-pad" style={{ marginTop: 24 }}>
                <div className="eyebrow no-rule" style={{ marginBottom: 12 }}>Your draft</div>
                <div className="js-recap-line"><span>Type</span><strong>{cls.type}</strong></div>
                <div className="js-recap-line"><span>Goal</span><strong>{goal}</strong></div>
                <div className="js-recap-line"><span>Audience</span><strong>{audience}</strong></div>
                <div className="js-recap-line"><span>Modules</span><strong>{allChosen.length} · {hours % 1 === 0 ? hours : hours.toFixed(1)}h</strong></div>
              </div>
            </div>
            <div className="card card-pad">
              {!sent ? (
                <form onSubmit={(e) => { e.preventDefault(); const form = e.target; const f = window.TENDApi.formData(form); const em = Object.keys(f).find(k => /email/i.test(k)); window.TENDApi.guard(form, () => window.TENDApi.api('contact', { form: 'journey', name: f[Object.keys(f).find(k => /name/i.test(k))] || '', email: em ? f[em] : '', organisation: f[Object.keys(f).find(k => /organisation/i.test(k))] || '', message: f[Object.keys(f).find(k => /know/i.test(k))] || '', details: { type: cls.type, goal, audience, modules: allChosen.map(m => m.t || m.title || m.name || String(m)), hours } }).then(() => setSent(true)).catch(err => alertBox(form, err.message))); }}>
                  <div style={{ display: 'grid', gap: 16 }}>
                    <Field label="Your name" placeholder="Helena Marais" required />
                    <Field label="Work email" type="email" placeholder="helena@company.com" required />
                    <Field label="Organisation" placeholder="Company name" />
                    <Field label="Anything we should know" as="textarea" rows={3} placeholder="Timing, cohort size, context…" hint="Optional." />
                    <Button variant="accent" energy="aqua" size="lg" type="submit" style={{ width: '100%' }}>Send request</Button>
                    <p className="caption center" style={{ margin: 0 }}>We reply within 48 hours.</p>
                  </div>
                </form>
              ) : (
                <div className="center" style={{ padding: '32px 8px' }}>
                  <div style={{ display: 'inline-flex', marginBottom: 16 }} dangerouslySetInnerHTML={{ __html: window.TENDCompass.render({ ...energy, size: 140, style: 'field', labels: false }) }} />
                  <h3 className="display-s">Request received.</h3>
                  <p className="body" style={{ marginTop: 10 }}>We will reply within 48 hours to talk through your programme.</p>
                  <p className="signoff" style={{ color: 'var(--aqua-deep)', marginTop: 20 }}>Now go tend to it.</p>
                </div>
              )}
            </div>
          </div>
        </div>
      </section>

      <Footer />
    </>
  );
}

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