/* =========================================================
   "How we met" — a scroll-driven, pinned cinematic sequence.
   Lightning in a Bottle, 2025. Igor is walking. Then Lily,
   a tiny thing in a bundled-up hoodie, powers right past him.
   ========================================================= */
const clamp = (v, a = 0, b = 1) => Math.max(a, Math.min(b, v));
const seg = (p, a, b) => clamp((p - a) / (b - a));
const lerp = (a, b, t) => a + (b - a) * t;

function beat(p, start, end, fade = 0.05) {
  let o = 0;
  if (p >= start && p <= end) {
    if (p < start + fade) o = (p - start) / fade;
    else if (p > end - fade) o = (end - p) / fade;
    else o = 1;
  }
  return { o: clamp(o), local: seg(p, start, end) };
}

const CROWD_BASE = "\\o/   \\o    o/   \\o/   \\o    \\o/    o/   \\o/   \\o    o/   ";
const CROWD = CROWD_BASE.repeat(4);

function MeetScrolly() {
  const ref = useRef(null);
  const [p, setP] = useState(0);

  useEffect(() => {
    let raf = 0;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        raf = 0;
        const el = ref.current;
        if (!el) return;
        const r = el.getBoundingClientRect();
        const total = el.offsetHeight - window.innerHeight;
        const prog = clamp(-r.top / total);
        setP(window.__scrollyForceP != null ? window.__scrollyForceP : prog);
      });
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => { window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); cancelAnimationFrame(raf); };
  }, []);

  // beats
  const b1 = beat(p, 0.00, 0.17);
  const b1o = p < 0.12 ? 1 : clamp((0.17 - p) / 0.05);
  const b2 = beat(p, 0.17, 0.40);
  const run = beat(p, 0.38, 0.66);
  const b4 = beat(p, 0.64, 0.80);
  // finale fades IN over 0.80–0.87 then holds full to the end (no quick fade-out)
  const b5o = clamp(seg(p, 0.80, 0.87));
  const b5local = seg(p, 0.80, 1.0);

  // Igor and Lily share one frame, moving at different rates.
  // Igor strolls slowly left→right; Lily comes barrelling in fast and collides ~0.64.
  const igorWalk = lerp(34, 60, clamp(seg(p, 0.17, 0.63)));
  const knock = clamp(seg(p, 0.63, 0.71));     // bowled over
  const recover = clamp(seg(p, 0.74, 0.80));   // springs back up, smitten
  const igorTip = lerp(0, 88, knock) * (1 - recover);
  // during the finale, glide the smitten pair together and settle them low
  const couple = clamp(seg(p, 0.80, 0.90));
  const igorX = lerp(igorWalk + knock * 6, 42, couple);
  const lilyXbase = lerp(-22, 45, clamp(seg(p, 0.40, 0.64)));
  const lilyX = lerp(lilyXbase, 58, couple);
  const figBottom = lerp(30 - knock * 9 * (1 - recover), 9, couple);
  const igorO = clamp(seg(p, 0.16, 0.21));
  const lilyO = clamp(seg(p, 0.39, 0.44));
  const impact = Math.sin(clamp(seg(p, 0.62, 0.72)) * Math.PI);
  const smitten = p > 0.74;
  const igorFace = p < 0.63 ? "(•_•)" : (p < 0.74 ? "(×_×)" : "(♥‿♥)");
  const beat4line = p < 0.75 ? "…and knocked Igor clean off his feet." : "He's been head-over-heels ever since.";
  // night gets warmer toward the meeting
  const warmth = clamp(seg(p, 0.55, 0.9));
  const bg = `radial-gradient(120% 90% at 50% ${lerp(18, 40, warmth)}%, rgba(185,125,82,${lerp(0.08, 0.34, warmth)}), transparent 55%), linear-gradient(180deg, #2c3326 0%, #1a1f15 55%, #20281b 100%)`;
  const crowdX = lerp(-6, -32, p);

  return (
    <div className="scrolly" ref={ref}>
      <div className="scrolly__pin" style={{ background: bg }}>
        <div className="scrolly__grain"></div>
        {b1o > 0.2 && <div className="scrolly__flash"></div>}

        {/* drifting crowd of little festival figures */}
        <div className="scrolly__crowd" style={{ transform: `translateX(${crowdX}%)`, opacity: lerp(0.18, 0.5, run.o) }}>
          {CROWD}
        </div>
        <div className="scrolly__crowd scrolly__crowd--2" style={{ transform: `translateX(${-crowdX * 0.6}%)`, opacity: 0.14 }}>
          {CROWD}
        </div>

        {/* progress rail */}
        <div className="scrolly__rail"><span style={{ height: (p * 100) + "%" }}></span></div>

        {/* BEAT 1 — LIB title */}
        <div className="scrolly__beat" style={{ opacity: b1o, transform: `translateY(${lerp(-18, 18, b1.local)}px)` }}>
          <svg className="scrolly__bolt" width="40" height="78" viewBox="0 0 40 78" fill="none" aria-hidden="true">
            <path d="M24 3 L7 43 H19 L15 75 L34 30 H22 L27 3 Z" stroke="#d9cba0" strokeWidth="1.3" strokeLinejoin="round" strokeLinecap="round" />
          </svg>
          <div className="scrolly__kicker">Spring 2025 · Buena Vista, CA</div>
          <h3 className="scrolly__title">Lightning<span>in a</span>Bottle</h3>
          <p className="scrolly__sub">There was no <em>us</em> yet. Just dust, bass, and a few thousand strangers.</p>
        </div>

        {/* BEAT 2 — Igor walking */}
        <div className="scrolly__beat" style={{ opacity: b2.o, transform: `translateY(${lerp(-14, 14, b2.local)}px)` }}>
          <div className="scrolly__line">Igor was just walking somewhere.</div>
          <p className="scrolly__sub">No plan. No idea. The desert going gold, the music a long way off.</p>
        </div>

        {/* BEAT 3 — Lily powers through */}
        <div className="scrolly__beat scrolly__beat--top" style={{ opacity: run.o }}>
          <div className="scrolly__line scrolly__line--big">…then a tiny thing in a bundled-up hoodie</div>
          <p className="scrolly__sub" style={{ opacity: seg(run.local, 0.3, 0.6) }}>came barrelling through the crowd — so full of joy.</p>
        </div>

        {/* Igor & Lily share the frame, moving at different rates */}
        <div className={"scrolly__igor" + (smitten ? " is-smitten" : "")} style={{ left: igorX + "%", bottom: figBottom + "%", opacity: igorO, transform: `translateX(-50%) rotate(${igorTip}deg)` }}>
          {smitten && <span className="igor-hearts"><span>♥</span><span>♥</span><span>♥</span></span>}
          <span className="kao">{igorFace}</span>
          <span className="tag">Igor</span>
        </div>
        <div className="scrolly__lily" style={{ left: lilyX + "%", bottom: figBottom + "%", opacity: lilyO }}>
          {smitten && <span className="igor-hearts"><span>♥</span><span>♥</span><span>♥</span></span>}
          <span className="trail" style={{ opacity: clamp(seg(p, 0.40, 0.55)) * (1 - knock) }}>✦ ✶ · ✦</span>
          <span className="kao kao--lily">{"ᕕ(ᐛ)ᕗ"}</span>
          <span className="tag">Lily</span>
        </div>
        {impact > 0.03 && (
          <div className="scrolly__impact" style={{ opacity: impact, bottom: "37%", left: ((igorX + lilyX) / 2) + "%" }}>
            <span className="impact__stars">✦ ✺ ✦</span>
            <span className="impact__pow">whomp!</span>
          </div>
        )}

        {/* BEAT 4 — the collision */}
        <div className="scrolly__beat scrolly__beat--lower" style={{ opacity: b4.o, transform: `translateY(${lerp(16, -8, b4.local)}px)` }}>
          <div className="scrolly__line">{beat4line}</div>
        </div>

        {/* BEAT 5 — outro */}
        <div className="scrolly__beat scrolly__beat--raise" style={{ opacity: b5o, transform: `translateY(${lerp(20, 0, clamp(b5local / 0.5))}px)` }}>
          <div className="scrolly__b5hearts" aria-hidden="true"><span>♥</span><span>♥</span><span>♥</span><span>♥</span><span>♥</span></div>
          <div className="scrolly__kicker">fast-forward one year</div>
          <h3 className="scrolly__title scrolly__title--sm">We're getting<br />married.</h3>
          <p className="scrolly__sub">September 2026, on the playa at Burning Man — and you're invited.</p>
        </div>

        {/* persistent hint, fades after start */}
        <div className="scrolly__hint" style={{ opacity: clamp(1 - p * 8) }}>scroll slowly ↓</div>
      </div>
    </div>
  );
}

window.MeetScrolly = MeetScrolly;
