// waiv-interactive.jsx — playable, scroll-synced rebuilds of HowItWorks,
// ShareGrid (→ orbit), Onelynk (→ ripple + switcher) and ForBusiness (count-up).
// These override the globals defined in waiv-home-sections.jsx (loaded earlier).

(function () {
  const { useState, useRef, useEffect } = React;
  const clamp = (v, a, b) => Math.min(b, Math.max(a, v));
  const ease = t => t * t * (3 - 2 * t);
  const mix = (a, b, t) => a + (b - a) * t;

  // fire `cb` once when the element scrolls into view
  function useInView(opts = { threshold: 0.3 }) {
    const ref = useRef(null);
    const [seen, setSeen] = useState(false);
    useEffect(() => {
      const el = ref.current; if (!el) return;
      const io = new IntersectionObserver(([e]) => {
        if (e.isIntersecting) { setSeen(true); io.disconnect(); }
      }, opts);
      io.observe(el);
      return () => io.disconnect();
    }, []);
    return [ref, seen];
  }

  /* ══════════════ HOW IT WORKS — interactive 3-step demo ══════════════ */
  function HowItWorks() {
    const steps = [
      { t: 'Tap your waiv to a phone', d: 'Hold the card near the top of any phone. The NFC chip wakes instantly — no app, no scan, no pairing.' },
      { t: 'Your Onelynk opens', d: 'A full-screen profile loads in their browser in under a second — photo, links and a save button.' },
      { t: 'They keep you for good', d: 'One tap drops your details into their contacts. Edit your profile anytime and every card updates.' },
    ];
    const [stage, setStage] = useState(0);
    const secRef = useRef(null);
    const stageElRef = useRef(null);
    const runRef = useRef(null);
    useEffect(() => {
      const timers = [];
      let armed = true;
      const run = () => {
        timers.forEach(clearTimeout); timers.length = 0;
        setStage(0);
        timers.push(setTimeout(() => setStage(1), 1900));
        timers.push(setTimeout(() => setStage(2), 3900));
      };
      runRef.current = run;
      const check = () => {
        const el = stageElRef.current; if (!el) return;
        const r = el.getBoundingClientRect();
        const vis = r.top < window.innerHeight * 0.82 && r.bottom > window.innerHeight * 0.18;
        if (vis && armed) { armed = false; run(); }
        else if (!vis && r.bottom < 0 || r.top > window.innerHeight) { armed = true; }
      };
      window.addEventListener('scroll', check, { passive: true });
      window.addEventListener('resize', check);
      const id = setTimeout(check, 300);
      return () => { window.removeEventListener('scroll', check); window.removeEventListener('resize', check); clearTimeout(id); timers.forEach(clearTimeout); };
    }, []);
    const replay = () => runRef.current && runRef.current();

    const screenCls = stage === 0 ? 's1' : stage === 1 ? 's2' : 's3 done';

    return (
      <section className="wv-sec" id="how" ref={secRef}>
        <div className="wv-container">
          <div className="wv-sec-head" data-reveal>
            <Kicker>HOW IT WORKS</Kicker>
            <h2 className="wv-sec-title">Three seconds from <em>stranger</em> to saved.</h2>
            <p className="wv-sec-lede">The whole exchange, start to finish — it plays as you scroll in. No app to download, for you or for them.</p>
          </div>
          <div className="iw">
            <div data-reveal>
              <div className="iw-steps">
                {steps.map((s, i) => {
                  const done = stage > i, active = stage === i;
                  const w = (active || done) ? 100 : 0;
                  return (
                    <div key={i} className={`iw-step ${active ? 'is-active' : ''} ${done ? 'is-done' : ''}`} onClick={replay}>
                      <div className="iw-step-prog" style={{ width: w + '%' }} />
                      <div className="iw-step-num">{done ? <svg viewBox="0 0 24 24"><path d="M5 13l4 4L19 7" strokeLinecap="round" strokeLinejoin="round" /></svg> : i + 1}</div>
                      <div>
                        <h3>{s.t}</h3>
                        <p>{s.d}</p>
                      </div>
                    </div>
                  );
                })}
              </div>
              <div className="iw-dots3">
                {steps.map((_, i) => <button key={i} className={`iw-dot3 ${stage === i ? 'is-on' : ''}`} onClick={replay} aria-label={`Step ${i + 1}`} />)}
              </div>
            </div>

            <div className={`iw-stage is-stage${stage} ${stage === 0 ? 'is-pulsing' : ''}`} ref={stageElRef}>
              <div className="iw-stage-glow" />

              {/* the tapping card (only beat 1) */}
              <div className="iw-tapcard wv-card--midnightgold">
                <img className="iw-card-logo" src={(window.__resources&&window.__resources.logoYellow)||"assets/waiv-yellow.png"} alt="" />
                <div className="iw-card-nfc" />
                <span className="iw-tapcard-hint">tap</span>
              </div>
              <div className="iw-tap"><span /><span /><span /></div>

              <div className="iw-phone">
                <div className="iw-notch" />
                <div className={`iw-screen ${screenCls}`}>
                  <div className="iw-pcover" />
                  <div className="iw-skel"><i /><i /><i /><i /></div>
                  <div className="iw-pbody">
                    <div className="iw-pav" />
                    <h3 className="iw-pname">Maya Okafor</h3>
                    <p className="iw-prole">Product Designer · Studio North</p>
                    <div className="iw-plinks">
                      <div className="iw-plink"><div className="iw-plink-ico"><Ico n="grid" /></div><b>Portfolio</b></div>
                      <div className="iw-plink"><div className="iw-plink-ico"><Ico n="calendar" /></div><b>Book a coffee</b></div>
                      <div className="iw-plink"><div className="iw-plink-ico"><Ico n="share" /></div><b>Instagram</b></div>
                    </div>
                    <div className="iw-psave">Save contact</div>
                  </div>
                  <div className="iw-saved">
                    <div className="iw-check"><svg viewBox="0 0 24 24"><path d="M5 13l4 4L19 7" /></svg></div>
                    <b>Saved to contacts</b>
                    <span>in 3 seconds · no app</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>
    );
  }

  /* ══════════════ SHARE — interactive orbit ══════════════ */
  function ShareGrid() {
    const nodes = [
      { ico: 'user', label: 'Contacts', title: 'Your contact card', desc: 'Name, number, email and address drop straight into their phone in a single tap — no typing, no typos.', chips: ['vCard', 'Apple Wallet', 'Google Contacts'] },
      { ico: 'share', label: 'Socials', title: 'Every handle, one tap', desc: 'Link all your profiles so people follow you on the platform they actually use — without spelling out usernames.', chips: ['Instagram', 'LinkedIn', 'X', 'TikTok', 'YouTube'] },
      { ico: 'card', label: 'Payments', title: 'Get paid on the spot', desc: 'Surface your payment links the moment you meet, so splitting a bill or closing a sale takes seconds.', chips: ['Venmo', 'PayPal', 'Cash App', 'UPI'] },
      { ico: 'grid', label: 'Portfolio', title: 'Show your best work', desc: 'Point to your site, store, menu or reel. Anything with a URL becomes a tappable block on your profile.', chips: ['Website', 'Behance', 'Dribbble', 'PDF'] },
      { ico: 'calendar', label: 'Booking', title: 'Let them book you', desc: 'Drop your calendar link and turn a handshake into a meeting before either of you leaves the room.', chips: ['Calendly', 'Cal.com', 'Google'] },
      { ico: 'wifi', label: 'Extras', title: 'And everything else', desc: 'Guest Wi-Fi, reviews, a tip jar, a waiver, a menu — mix in whatever the moment calls for.', chips: ['Guest Wi-Fi', 'Reviews', 'Menu', 'Docs'] },
    ];
    const [active, setActive] = useState(0);
    const R = 38; // radius as % of stage
    const pos = nodes.map((_, i) => {
      const ang = (-90 + i * (360 / nodes.length)) * Math.PI / 180;
      return { x: 50 + R * Math.cos(ang), y: 50 + R * Math.sin(ang) };
    });
    const a = nodes[active];
    return (
      <section className="wv-sec so-sec" id="share">
        <div className="wv-container">
          <div className="wv-sec-head wv-sec-head--center" data-reveal>
            <Kicker>ONE TAP, EVERYTHING</Kicker>
            <h2 className="wv-sec-title">Share whatever matters <em>most.</em></h2>
            <p className="wv-sec-lede">Your waiv is a hub, not a business card. Tap a bubble to see what it can hand off — then mix and match your own.</p>
          </div>
          <div className="so-wrap">
            <div className="so-stage" data-reveal>
              <svg className="so-lines" viewBox="0 0 100 100" preserveAspectRatio="none">
                {pos.map((p, i) => (
                  <line key={i} x1="50" y1="50" x2={p.x} y2={p.y} className={i === active ? 'is-active' : ''} vectorEffect="non-scaling-stroke" />
                ))}
              </svg>
              {pos.map((p, i) => (
                <div key={i} className={`so-bubble ${i === active ? 'is-active' : ''}`}
                  style={{ left: p.x + '%', top: p.y + '%', transform: 'translate(-50%,-50%)', animationDelay: (-i * 0.7) + 's' }}
                  onMouseEnter={() => setActive(i)} onClick={() => setActive(i)}>
                  <div className="so-bubble-ico"><Ico n={nodes[i].ico} /></div>
                  <b>{nodes[i].label}</b>
                </div>
              ))}
              <div className="so-core"><img src={(window.__resources&&window.__resources.logoYellow)||"assets/waiv-yellow.png"} alt="waiv" /></div>
            </div>
            <div className="so-detail" data-reveal data-reveal-delay="1">
              <Kicker>{a.label.toUpperCase()}</Kicker>
              <div className="so-d-anim" key={active}>
                <div className="so-d-ico"><Ico n={a.ico} /></div>
                <h3 className="so-d-title">{a.title}</h3>
                <p className="so-d-desc">{a.desc}</p>
                <div className="so-d-chips">{a.chips.map(c => <b key={c}>{c}</b>)}</div>
              </div>
              <div className="so-hint">Hover the bubbles →</div>
            </div>
          </div>
        </div>
      </section>
    );
  }

  /* ══════════════ ONELYNK — ripple + feature switcher ══════════════ */
  function Onelynk() {
    const feats = [
      { id: 'edit', ico: 'edit', t: 'Edit once, update everywhere', p: 'Change a job, a number, a link — every card you ever handed out reflects it instantly.' },
      { id: 'analytics', ico: 'chart', t: 'See who you’re connecting with', p: 'Live analytics on taps, views and saved contacts — know exactly which rooms are working.' },
      { id: 'noapp', ico: 'bolt', t: 'No app for anyone', p: 'Your profile is just a web link. The person tapping needs nothing installed, ever.' },
    ];
    const [feat, setFeat] = useState('edit');
    const [bursts, setBursts] = useState([]);
    const onPick = (id) => {
      setFeat(id);
      const key = Date.now();
      setBursts(b => [...b, key]);
      setTimeout(() => setBursts(b => b.filter(k => k !== key)), 900);
    };
    const bars = [40, 62, 48, 78, 95, 70, 88];
    return (
      <section className="wv-sec wv-onelynk" id="onelynk">
        <div className="ol-ripple" aria-hidden="true"><span /><span /><span /><span />
          {bursts.map(k => <div key={k} className="ol-burst" />)}
        </div>
        <div className="wv-container">
          <div className="wv-ol-layout">
            <div data-reveal>
              <Kicker>ONELYNK</Kicker>
              <h2 className="wv-sec-title">One link that <em>is</em> you.</h2>
              <p className="wv-sec-lede">Every waiv points to your Onelynk — a living profile you control from your phone. Tap a feature to see it in action.</p>
              <div className="wv-ol-feats" style={{ margin: '30px 0 34px' }}>
                {feats.map(f => (
                  <div key={f.id} className={`ol-feat ${feat === f.id ? 'is-active' : ''}`} onClick={() => onPick(f.id)}>
                    <div className="ol-feat-ico"><Ico n={f.ico} /></div>
                    <div><h4>{f.t}</h4><p>{f.p}</p></div>
                  </div>
                ))}
              </div>
              <button className="wv-btn wv-btn-primary wv-magnetic">Claim your Onelynk <span className="wv-arrow">→</span></button>
            </div>
            <div className="wv-ol-stage" data-reveal data-reveal-delay="1">
              <div className="wv-ol-float wv-ol-float-1"><div className="wv-num">1.2k</div><div className="wv-cap">profile<br />views</div></div>
              <div className="wv-ol-float wv-ol-float-2"><div className="wv-num">+318</div><div className="wv-cap">contacts<br />saved</div></div>
              <div className="wv-ol-phone">
                <div className="wv-ol-notch" />
                <div className="wv-ol-screen">
                  <div className="wv-ol-cover" />
                  <div className="wv-ol-body">
                    <div className="wv-ol-avatar" />
                    <h3 className="wv-ol-name">Maya Okafor</h3>
                    <p className="wv-ol-role">Product Designer · Studio North</p>
                    <span className="wv-ol-tag">⚡ via waiv</span>
                    <div className="wv-ol-links">
                      <div className="wv-ol-link"><div className="wv-ol-link-ico"><Ico n="grid" /></div><div className="wv-ol-link-txt"><b>Portfolio</b><span>maya.design</span></div></div>
                      <div className="wv-ol-link"><div className="wv-ol-link-ico"><Ico n="calendar" /></div><div className="wv-ol-link-txt"><b>Book a coffee</b><span>cal.com/maya</span></div></div>
                      <div className="wv-ol-link"><div className="wv-ol-link-ico"><Ico n="share" /></div><div className="wv-ol-link-txt"><b>Instagram</b><span>@maya.makes</span></div></div>
                    </div>
                    <div className="wv-ol-save">Save contact</div>
                  </div>

                  {/* feature overlays */}
                  <div className={`ol-ovl ${feat === 'edit' ? 'is-on' : ''}`}>
                    <div className="ol-edit-badge"><span style={{ width: 6, height: 6, borderRadius: 9, background: 'var(--navy)' }} />Editing live</div>
                    <div className="ol-edit-ring" style={{ top: 150 }} />
                  </div>
                  <div className={`ol-ovl ${feat === 'noapp' ? 'is-on' : ''}`}>
                    <div className="ol-url"><span className="ol-url-dot" /><b>onelynk.to/maya</b><small>no app</small></div>
                  </div>
                  <div className={`ol-ovl ${feat === 'analytics' ? 'is-on' : ''}`}>
                    <div className="ol-anal">
                      <div className="ol-anal-h"><b>This week</b><span>▲ 24%</span></div>
                      <div className="ol-bars">{bars.map((h, i) => <i key={i} style={{ height: h + '%', transitionDelay: (i * 0.05) + 's' }} />)}</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>
    );
  }

  /* ══════════════ FOR BUSINESS — count-up stats ══════════════ */
  function CountUp({ to, decimals = 0, suffix = '', dur = 1400 }) {
    const [ref, seen] = useInView({ threshold: 0.5 });
    const [val, setVal] = useState(0);
    useEffect(() => {
      if (!seen) return;
      let raf, start;
      const step = (now) => {
        if (!start) start = now;
        const p = ease(clamp((now - start) / dur, 0, 1));
        setVal(to * p);
        if (p < 1) raf = requestAnimationFrame(step);
      };
      raf = requestAnimationFrame(step);
      return () => cancelAnimationFrame(raf);
    }, [seen]);
    return <b ref={ref}>{val.toFixed(decimals)}<em>{suffix}</em></b>;
  }

  function ForBusiness() {
    const cards = [
      { ico: 'users', t: 'Equip the whole team', p: 'Order matching cards for everyone and manage every profile from one dashboard.' },
      { ico: 'building', t: 'On-brand, every tap', p: 'Lock logos, colours and layout so every profile looks unmistakably yours.' },
      { ico: 'refresh', t: 'CRM in real time', p: 'Pipe captured leads straight into Salesforce, HubSpot or a webhook automatically.' },
    ];
    return (
      <section className="wv-sec wv-biz" id="business">
        <div className="wv-container">
          <div className="wv-sec-head wv-sec-head--center" data-reveal>
            <Kicker>FOR BUSINESS</Kicker>
            <h2 className="wv-sec-title">Networking that scales <em>with the team.</em></h2>
            <p className="wv-sec-lede">From two-person studios to thousand-seat sales floors — deploy, brand and measure every connection from one place.</p>
          </div>
          <div className="wv-biz-grid">
            {cards.map((c, i) => (
              <div className="wv-biz-card" key={i} data-reveal data-reveal-delay={i + 1}>
                <div className="wv-biz-ico"><Ico n={c.ico} /></div>
                <h4>{c.t}</h4><p>{c.p}</p>
              </div>
            ))}
          </div>
          <div className="wv-biz-stats" data-reveal>
            <div className="wv-biz-stat"><CountUp to={7} suffix="×" /><span>more contacts kept</span></div>
            <div className="wv-biz-stat"><CountUp to={40} suffix="k+" /><span>professionals on waiv</span></div>
            <div className="wv-biz-stat"><CountUp to={1.4} decimals={1} suffix="m" /><span>taps shared</span></div>
          </div>
        </div>
      </section>
    );
  }

  Object.assign(window, { HowItWorks, ShareGrid, Onelynk, ForBusiness });
})();
