/* global React */
const { useState: useEngState, useEffect: useEngEffect, useRef: useEngRef } = React;

const ENGINE_STEPS = [
  ["01", "Backend systems & infrastructure", "CRM, tracking dashboards, automations, and payment processing. The operational spine the whole business runs on."],
  ["02", "Marketing ecosystem", "Customer acquisition funnel, new-opportunity framing, awareness funnel, and ongoing offer optimization."],
  ["03", "Content strategy & ideation", "Proven content formats that move the audience through the awareness stages and customer journey until they're ready to buy."],
  ["04", "Funnel buildout", "Landing pages, high-converting email sequences, VSLs, sales assets, and DM setting frameworks."],
  ["05", "Launch campaigns", "Cohort launch strategy, a 21-day IG story sequence, a waitlist funnel, and the hype and urgency that drive it."],
  ["06", "Sales team", "Hiring, managing, and training the closers, setters, and dialers who run every conversation."],
  ["07", "Fulfillment structure", "Systems and infrastructure so the coach fulfills in just 2–3 hours a day."],
  ["08", "Scaling", "Webinar funnels and paid ads for reliable, long-term growth."],
];

function EngineHead() {
  return (
    <React.Fragment>
      <p className="smo-eyebrow">The engine · 01 · backend → 08 · scale</p>
      <h2 className="smo-h2 mk-section__title">
        The full stack. <span className="smo-accent">Handled for you.</span>
      </h2>
    </React.Fragment>
  );
}

/* Thin gold connector arrow that sits in the gap between cards. */
function ConnectorArrow() {
  return (
    <svg width="18" height="34" viewBox="0 0 18 34" fill="none" aria-hidden="true">
      <path d="M9 1 V29" stroke="currentColor" strokeWidth="1" />
      <path d="M3 23 L9 30 L15 23" stroke="currentColor" strokeWidth="1" fill="none" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

const CARD_H = 132;
const PITCH = 184; /* card (132) + arrow gap (52) */

/* Stacked numbered list — used both for the "grid" tweak and as the mobile
   fallback for the pinned laptop scroll (scroll-jacking is a poor phone UX). */
function EngineGrid() {
  return (
    <section id="engine" className="mk-section">
      <EngineHead />
      <div className="mk-engine">
        {ENGINE_STEPS.map(([n, t, d]) => (
          <div className="smo-numcard mk-engine__card" key={n}>
            <span className="smo-chip">{n}</span>
            <div>
              <div className="mk-engine__t">{t}</div>
              <div className="mk-engine__d">{d}</div>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

/* True on phones / short viewports, where the pinned scroll is replaced by the
   stacked list. Re-evaluates on resize + orientation change. */
function useIsCompact() {
  const [compact, setCompact] = useEngState(
    typeof window !== "undefined" &&
      window.matchMedia("(max-width: 760px), (max-height: 560px)").matches
  );
  useEngEffect(() => {
    const mq = window.matchMedia("(max-width: 760px), (max-height: 560px)");
    const on = () => setCompact(mq.matches);
    mq.addEventListener ? mq.addEventListener("change", on) : mq.addListener(on);
    return () => { mq.removeEventListener ? mq.removeEventListener("change", on) : mq.removeListener(on); };
  }, []);
  return compact;
}

/* ---------- Pinned scroll experience ----------
   The section is a tall scroll track; the laptop frame is sticky and centered.
   Scroll progress drives a filmstrip of cards through a 16:9 window: the active
   system sits centered, the next rises into place with a gold arrow between them. */
function EngineScreen() {
  const trackRef = useEngRef(null);
  const stageRef = useEngRef(null);
  const [p, setP] = useEngState(0);
  const [stageH, setStageH] = useEngState(320);
  const compact = useIsCompact();
  const N = ENGINE_STEPS.length;

  useEngEffect(() => {
    if (compact) return;
    let raf = 0;
    const compute = () => {
      raf = 0;
      const el = trackRef.current;
      if (!el) return;
      const vh = window.innerHeight;
      const range = el.offsetHeight - vh;
      const scrolled = Math.min(Math.max(-el.getBoundingClientRect().top, 0), Math.max(range, 1));
      setP(range > 0 ? scrolled / range : 0);
      if (stageRef.current) setStageH(stageRef.current.clientHeight);
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(compute); };
    compute();
    window.addEventListener("scroll", onScroll, { passive: true, capture: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll, { capture: true });
      window.removeEventListener("resize", onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, [compact]);

  // On phones / short viewports, skip the pinned scroll entirely.
  if (compact) return <EngineGrid />;

  const active = p * (N - 1);                         // 0 .. N-1
  const activeIdx = Math.round(active);
  const current = Math.min(N, activeIdx + 1);
  const offset = stageH / 2 - CARD_H / 2 - active * PITCH;
  const trackH = 100 + (N - 1) * 45;                  // vh of scroll runway

  return (
    <section id="engine" ref={trackRef} className="lp-engtrack" style={{ height: trackH + "vh" }}>
      <div className="lp-engtrack__sticky">
        <div className="lp-engtrack__inner">
          <EngineHead />
          <div className="lp-laptop">
            <div className="lp-laptop__screen">
              <div className="lp-laptop__cam" />
              <div className="lp-screen__body">
                <div className="lp-screen__head">
                  <span className="dot" /> Fulfillment engine
                  <span className="right smo-num">
                    {String(current).padStart(2, "0")} / {String(N).padStart(2, "0")}
                  </span>
                </div>
                <div className="lp-screen__stage" ref={stageRef}>
                  <div className="lp-stage-fade lp-stage-fade--top" />
                  <div className="lp-filmstrip" style={{ transform: `translateY(${offset}px)` }}>
                    {ENGINE_STEPS.map(([n, t, d], i) => (
                      <React.Fragment key={n}>
                        <div className="lp-film__card" data-active={activeIdx === i}>
                          <div className="lp-film__top">
                            <span className="smo-chip">{n}</span>
                            <span className="lp-film__of smo-mono">/ {String(N).padStart(2, "0")}</span>
                          </div>
                          <h3 className="lp-film__title">{t}</h3>
                          <p className="lp-film__desc">{d}</p>
                        </div>
                        {i < N - 1 && <div className="lp-film__arrow"><ConnectorArrow /></div>}
                      </React.Fragment>
                    ))}
                  </div>
                  <div className="lp-stage-fade lp-stage-fade--bottom" />
                </div>
              </div>
            </div>
            <div className="lp-laptop__base" />
          </div>
          <div className="lp-screen__progress" aria-hidden="true">
            {ENGINE_STEPS.map((_, i) => (
              <span key={i} className={"lp-screen__tick" + (i <= active + 0.001 ? " is-on" : "")} />
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function LpEngine({ variant = "grid" }) {
  if (variant === "screen") return <EngineScreen />;
  return <EngineGrid />;
}

Object.assign(window, { LpEngine });
