// sections.jsx - the body of the site: the scrollytelling ritual, feature cards,
// pairing steps, and the cross-device showcase.
(function () {
  const { KissMark } = window.BisouxDesignSystem_144cac;
  const Ic = window.BxIcon;

  // ---- 1. The daily ritual (pinned scrollytelling) -----------------------
  function Ritual() {
    const { BxPhoneFrame, BxAppHomeMathis, BxAppGratitude, BxAppMoments } = window;
    const steps = [
      { k: "Send a bisou", t: "The smallest gesture, and the whole point.", d: "One tap sends a single kiss. It presses in and blooms open on their screen - a heartbeat between you, no words needed.", I: KissMark },
      { k: "Daily gratitude", t: "One thank-you, revealed side by side.", d: "Write one thing you're grateful to them for. Yours stays sealed until theirs is written, then they open together. No rush.", I: Ic.sparkle },
      { k: "Moments", t: "A glimpse that fades - unless it's kept.", d: "Quick live photos that disappear in a day. A bisou on one keeps it forever, into Kept. A keepsake, never a streak.", I: Ic.camera },
    ];
    return (
      <section className="section" style={{ background: "var(--surface)", borderTop: "1px solid var(--border)", borderBottom: "1px solid var(--border)" }} data-scrolly>
        <div className="wrap scrolly-grid">
          {/* sticky phone stage */}
          <div className="scrolly-sticky" style={{ height: "100vh" }}>
            <BxPhoneFrame data-ritual-phone>
              <div className="scrolly-screen show" data-step="0"><BxAppHomeMathis /></div>
              <div className="scrolly-screen" data-step="1"><BxAppGratitude /></div>
              <div className="scrolly-screen" data-step="2"><BxAppMoments /></div>
            </BxPhoneFrame>
          </div>

          {/* the three reading steps */}
          <div style={{ paddingTop: "12vh", paddingBottom: "12vh" }}>
            <p className="eyebrow reveal" style={{ marginBottom: 18 }}>One quiet reason, each day</p>
            {steps.map((s, i) => (
              <div
                key={i}
                data-step={i}
                className="scrolly-step"
              >
                <span style={{ width: 52, height: 52, borderRadius: 16, background: "var(--accent-soft)", color: "var(--accent)", display: "inline-flex", alignItems: "center", justifyContent: "center", marginBottom: 22 }}>
                  {s.I === KissMark ? <KissMark tone="accent" size={26} /> : <s.I size={26} />}
                </span>
                <p className="bx-label" style={{ marginBottom: 12, color: "var(--accent)" }}>{s.k}</p>
                <h2 className="display" style={{ fontSize: "clamp(30px, 3.4vw, 44px)", marginBottom: 18 }}>{s.t}</h2>
                <p className="lede">{s.d}</p>
              </div>
            ))}
          </div>
        </div>
      </section>
    );
  }

  // ---- 2. Feature cards ---------------------------------------------------
  function Features() {
    const cards = [
      { I: Ic.heart, k: "Presence", t: "Send a bisou", d: "The signature gesture. A single kiss that lands soft, anytime - the heartbeat of your space." },
      { I: Ic.sparkle, k: "Appreciation", t: "Daily gratitude", d: "Two small thank-yous, revealed side by side. Closeness as an invitation, never homework." },
      { I: Ic.sun, k: "Together, apart", t: "Today", d: "Your two days, laid side by side, so you stay in each other's hours even when miles apart." },
      { I: Ic.camera, k: "Keepsakes", t: "Moments & Kept", d: "Glimpses that fade in a day. A bisou keeps the one you love, forever - never a streak." },
    ];
    const stageRef = React.useRef(null);
    const capRef = React.useRef(null);

    React.useEffect(() => {
      const stage = stageRef.current, cap = capRef.current;
      if (!stage || !cap) return;
      const orbs = Array.from(stage.querySelectorAll(".feat-orb"));
      const N = orbs.length;
      const capLabel = cap.querySelector("[data-cap-label]");
      const capTitle = cap.querySelector("[data-cap-title]");
      const capDesc = cap.querySelector("[data-cap-desc]");
      const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
      let Rx = 240, Ry = 52;
      function measure() {
        const w = stage.clientWidth || 700;
        Rx = Math.max(120, Math.min(250, w * 0.33));
        Ry = Rx * 0.22;
      }
      measure();

      let lastActive = -1;
      function setCaption(i) {
        if (i === lastActive) return;
        lastActive = i;
        cap.style.opacity = "0";
        window.setTimeout(() => {
          if (capLabel) capLabel.textContent = cards[i].k;
          if (capTitle) capTitle.textContent = cards[i].t;
          if (capDesc) capDesc.textContent = cards[i].d;
          cap.style.opacity = "1";
        }, 200);
      }

      function layout(a) {
        let best = 0, bd = -2;
        orbs.forEach((orb, i) => {
          const ai = a + i * (2 * Math.PI / N);
          const depth = Math.cos(ai);            // -1 (back) .. 1 (front)
          const x = Math.sin(ai);
          const f = (depth + 1) / 2;             // 0..1
          const scale = 0.56 + f * 0.62;
          const tx = x * Rx;
          const ty = -depth * Ry;                // tilt: front sits lower
          orb.style.transform =
            `translate(-50%, -50%) translate(${tx.toFixed(1)}px, ${ty.toFixed(1)}px) scale(${scale.toFixed(3)})`;
          orb.style.zIndex = String(Math.round(f * 100));
          orb.style.opacity = (0.4 + f * 0.6).toFixed(2);
          orb.style.filter = depth < -0.15 ? `blur(${(-depth * 2.4).toFixed(1)}px)` : "none";
          orb.classList.toggle("is-front", false);
          if (depth > bd) { bd = depth; best = i; }
        });
        orbs[best].classList.add("is-front");
        setCaption(best);
      }

      layout(0);
      if (reduce) return;

      // angle is driven by three sources, all additive:
      //   • a very gentle idle drift so it's alive
      //   • page scroll - scrolling turns the ring
      //   • user drag / wheel - grab and spin, with inertia
      let angle = 0, vel = 0, raf = 0, lastT = null;
      let dragging = false, dragStartX = 0, dragStartAngle = 0, lastDX = 0;
      let lastScrollY = window.scrollY || 0;
      const DRIFT = 0.00009;     // rad/ms idle
      const SCROLL_K = 0.0019;   // rad per px scrolled
      const DRAG_K = 0.0095;     // rad per px dragged
      const WHEEL_K = 0.0010;    // spin impulse per wheel unit
      const FRICTION = 0.92;

      function frame(t) {
        const dt = lastT == null ? 16 : Math.min(40, t - lastT);
        lastT = t;
        if (dragging) {
          // angle set directly by the drag handler
        } else {
          const sy = window.scrollY || 0;
          angle += (sy - lastScrollY) * SCROLL_K;
          lastScrollY = sy;
          angle += DRIFT * dt + vel;
          vel *= FRICTION;
          if (Math.abs(vel) < 0.00002) vel = 0;
        }
        layout(angle);
        raf = requestAnimationFrame(frame);
      }
      raf = requestAnimationFrame(frame);

      // ---- drag to spin ----
      function onDown(e) {
        dragging = true; vel = 0; lastDX = 0;
        dragStartX = e.clientX; dragStartAngle = angle;
        stage.classList.add("grabbing");
        try { stage.setPointerCapture(e.pointerId); } catch (err) {}
      }
      function onMove(e) {
        if (!dragging) return;
        const dx = e.clientX - dragStartX;
        const prev = angle;
        angle = dragStartAngle - dx * DRAG_K;
        lastDX = angle - prev;
        layout(angle);
      }
      function onUp(e) {
        if (!dragging) return;
        dragging = false;
        vel = lastDX;                       // fling inertia
        lastScrollY = window.scrollY || 0;  // avoid a scroll jump on resume
        stage.classList.remove("grabbing");
        try { stage.releasePointerCapture(e.pointerId); } catch (err) {}
      }
      stage.addEventListener("pointerdown", onDown);
      stage.addEventListener("pointermove", onMove);
      stage.addEventListener("pointerup", onUp);
      stage.addEventListener("pointercancel", onUp);

      // ---- wheel over the stage adds a spin (page still scrolls) ----
      function onWheel(e) { vel += e.deltaY * WHEEL_K; }
      stage.addEventListener("wheel", onWheel, { passive: true });

      const onResize = () => measure();
      window.addEventListener("resize", onResize, { passive: true });

      return () => {
        cancelAnimationFrame(raf);
        stage.removeEventListener("pointerdown", onDown);
        stage.removeEventListener("pointermove", onMove);
        stage.removeEventListener("pointerup", onUp);
        stage.removeEventListener("pointercancel", onUp);
        stage.removeEventListener("wheel", onWheel);
        window.removeEventListener("resize", onResize);
      };
    }, []);

    return (
      <section id="features" className="section" style={{ padding: "120px 0", overflow: "hidden" }}>
        <div className="wrap" style={{ textAlign: "center" }}>
          <p className="eyebrow center reveal" style={{ marginBottom: 20 }}>What's inside</p>
          <h2 className="display reveal" data-delay="1" style={{ fontSize: "clamp(34px, 4.4vw, 56px)", maxWidth: 760, margin: "0 auto" }}>
            Small on purpose. <span className="emotive" style={{ color: "var(--accent)" }}>It does four things, gently.</span>
          </h2>

          <div className="feat-carousel-stage reveal" data-delay="2" ref={stageRef}>
            <div className="feat-orbit">
              {cards.map((c, i) => (
                <div key={i} className="feat-orb" data-i={i}>
                  <span className="feat-disc"><c.I size={38} /></span>
                </div>
              ))}
            </div>
          </div>

          <div className="feat-caption" ref={capRef}>
            <p className="bx-label" data-cap-label style={{ marginBottom: 8, color: "var(--accent)" }}>{cards[0].k}</p>
            <h3 className="display" data-cap-title style={{ fontSize: 28, marginBottom: 10 }}>{cards[0].t}</h3>
            <p data-cap-desc style={{ fontSize: 16, lineHeight: 1.6, color: "var(--text-secondary)", margin: 0 }}>{cards[0].d}</p>
          </div>
          <p className="reveal" data-delay="3" style={{ fontSize: 12.5, letterSpacing: "0.04em", color: "var(--text-secondary)", marginTop: 22, display: "inline-flex", alignItems: "center", gap: 8 }}>
            <Ic.arrowRight size={15} style={{ transform: "rotate(0deg)" }} /> drag or scroll to turn
          </p>
        </div>
      </section>
    );
  }

  // ---- 3. Pairing (how it works) -----------------------------------------
  function Pairing({ Screen }) {
    const { BxTabletFrame, BxAppToday } = window;
    const TabletScreen = Screen || BxAppToday;
    const steps = [
      { n: "1", t: "Create your space", d: "Open Bisoux and start a space that holds just the two of you. No profiles to browse, no one else to find." },
      { n: "2", t: "Invite your person", d: "Send one invite. The moment they arrive, your space comes alive - “Camille is here. Your space is ready.”" },
      { n: "3", t: "Open it, gently, each day", d: "A bisou, a thank-you, your two days side by side. That's the whole ritual. No rush, ever." },
    ];
    return (
      <section id="how" className="section" style={{ padding: "110px 0", background: "var(--surface)", borderTop: "1px solid var(--border)", borderBottom: "1px solid var(--border)" }}>
        <div className="wrap pair-grid">
          <div>
            <p className="eyebrow reveal" style={{ marginBottom: 22 }}>How pairing works</p>
            <h2 className="display reveal" data-delay="1" style={{ fontSize: "clamp(32px, 4vw, 50px)", marginBottom: 40 }}>
              A closed space, made for two - in about a minute.
            </h2>
            <div style={{ display: "flex", flexDirection: "column", gap: 26 }}>
              {steps.map((s, i) => (
                <div key={i} className="reveal" data-delay={Math.min(i + 1, 4)} style={{ display: "flex", gap: 18 }}>
                  <span className="step-num">{s.n}</span>
                  <div>
                    <h3 className="display" style={{ fontSize: 22, marginBottom: 6 }}>{s.t}</h3>
                    <p style={{ fontSize: 15.5, lineHeight: 1.6, color: "var(--text-secondary)", margin: 0, maxWidth: 420 }}>{s.d}</p>
                  </div>
                </div>
              ))}
            </div>
          </div>
          <div className="reveal r-right" data-delay="2" style={{ display: "flex", justifyContent: "center" }} data-tilt-area>
            <div data-scroll-rise="60">
              <BxTabletFrame data-tilt="5"><TabletScreen /></BxTabletFrame>
            </div>
          </div>
        </div>
      </section>
    );
  }

  // ---- 4. Cross-device showcase ------------------------------------------
  function Devices() {
    const { BxLaptopFrame, BxPhoneFrame, BxAppMoments, BxAppGratitude } = window;
    return (
      <section className="section" style={{ padding: "120px 0 130px", overflow: "hidden" }}>
        <div className="wrap" style={{ textAlign: "center", marginBottom: 64 }}>
          <p className="eyebrow center reveal" style={{ marginBottom: 20 }}>Phone · tablet · laptop</p>
          <h2 className="display reveal" data-delay="1" style={{ fontSize: "clamp(34px, 4.6vw, 58px)", maxWidth: 760, margin: "0 auto" }}>
            On every screen you share, the same quiet world.
          </h2>
          <p className="lede reveal" data-delay="2" style={{ margin: "20px auto 0", maxWidth: 540 }}>
            Bisoux follows you from pocket to desk - softly, never demanding. Your space, wherever the two of you are.
          </p>
        </div>
        <div className="wrap" style={{ position: "relative", display: "flex", justifyContent: "center", alignItems: "flex-end", minHeight: 520 }} data-tilt-area>
          <div className="reveal r-scale" data-delay="1" style={{ position: "relative", zIndex: 1 }}>
            <div data-scroll-scale="0.9">
              <BxLaptopFrame data-tilt="3"><BxAppMoments /></BxLaptopFrame>
            </div>
          </div>
          <div className="reveal devices-overlay-phone r-right" data-delay="3" data-parallax="-0.06" style={{ position: "absolute", right: "8%", bottom: -10, zIndex: 3 }}>
            <BxPhoneFrame data-tilt="6" style={{ width: 232 }}><BxAppGratitude /></BxPhoneFrame>
          </div>
        </div>
      </section>
    );
  }

  Object.assign(window, { BxRitual: Ritual, BxFeatures: Features, BxPairing: Pairing, BxDevices: Devices });
})();
