/* app.jsx — Brand Stack landing. Hero with router-diagram, grid, framing, capture, chatbot. */

/* Router-diagram in the hero. 6 endpoints align with the 6 cards below. */
function RouterDiagram({ hovered }) {
  const endpoints = [
    { id: "prompts",  x: 80,  label: "01 / Prompts" },
    { id: "reel",     x: 250, label: "02 / Reel" },
    { id: "creative", x: 420, label: "03 / Creative" },
    { id: "catalog",  x: 590, label: "04 / Catalog" },
    { id: "airtable", x: 760, label: "05 / Build" },
    { id: "drop",     x: 930, label: "06 / Drop" },
  ];
  const originX = 505;
  const originY = 10;
  const endY = 78;
  const pathRefs = React.useRef([]);
  const [lengths, setLengths] = React.useState({});

  React.useLayoutEffect(() => {
    const out = {};
    pathRefs.current.forEach((el, i) => {
      if (el) out[i] = Math.ceil(el.getTotalLength());
    });
    setLengths(out);
  }, []);

  return (
    <div className="diagram" aria-hidden="true">
      <svg viewBox="0 0 1010 96" preserveAspectRatio="none">
        <text className="diagram-origin-label" x={originX} y={originY - 2} textAnchor="middle">
          you are here
        </text>
        <circle className="diagram-origin" cx={originX} cy={originY + 4} r="3.5" />

        {endpoints.map((e, i) => {
          const mid = originY + (endY - originY) * 0.55;
          const d = `M ${originX} ${originY + 4} C ${originX} ${mid}, ${e.x} ${mid - 12}, ${e.x} ${endY - 6}`;
          const active = hovered === e.id;
          const len = lengths[i] || 400;
          const drawDelay = 700 + i * 90;
          const nodeDelay = drawDelay + 900;
          return (
            <g key={e.id}>
              <path
                ref={el => (pathRefs.current[i] = el)}
                d={d}
                className={`diagram-path${active ? " is-active" : ""}`}
                style={{ "--len": len, "--draw-delay": `${drawDelay}ms` }}
              />
              <circle
                cx={e.x}
                cy={endY - 4}
                r="3"
                className={`diagram-node${active ? " is-active" : ""}`}
                style={{ "--node-delay": `${nodeDelay}ms` }}
              />
              <text
                className="diagram-label"
                x={e.x}
                y={endY + 12}
                textAnchor="middle"
                style={{ "--node-delay": `${nodeDelay}ms` }}
              >
                {e.label}
              </text>
            </g>
          );
        })}
      </svg>
    </div>
  );
}

/* Headline with line-by-line stagger */
function HeroH1() {
  const lines = [
    "We don't sell services.",
    ["We ", { em: "route" }, " e-commerce brands"],
    "to the right lever for growth.",
  ];
  return (
    <h1 className="hero-h1">
      {lines.map((line, i) => {
        const delay = `${200 + i * 120}ms`;
        const content = Array.isArray(line)
          ? line.map((chunk, j) =>
              typeof chunk === "string"
                ? <React.Fragment key={j}>{chunk}</React.Fragment>
                : <em key={j}>{chunk.em}</em>
            )
          : line;
        return (
          <span key={i} className="line">
            <span style={{ "--line-delay": delay }}>{content}</span>
          </span>
        );
      })}
    </h1>
  );
}

/* Reveal-on-scroll helper hook */
function useReveal() {
  React.useEffect(() => {
    const els = document.querySelectorAll(".reveal");
    if (!("IntersectionObserver" in window)) {
      els.forEach(el => el.classList.add("is-in"));
      return;
    }
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add("is-in");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  }, []);
}

/* Tiny counter that ticks up when in view */
function Counter({ to, duration = 1400 }) {
  const [val, setVal] = React.useState(0);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) {
        const start = performance.now();
        const tick = (t) => {
          const p = Math.min(1, (t - start) / duration);
          const eased = 1 - Math.pow(1 - p, 3);
          setVal(Math.round(to * eased));
          if (p < 1) requestAnimationFrame(tick);
        };
        requestAnimationFrame(tick);
        io.disconnect();
      }
    }, { threshold: 0.6 });
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  return <span ref={ref}>{String(val).padStart(2, "0")}</span>;
}

function App() {
  const accent = "#3a5fc4";
  const accentSoft = "#e5ebf8";
  const [hovered, setHovered] = React.useState(null);
  const [botOpen, setBotOpen] = React.useState(false);

  React.useEffect(() => {
    document.documentElement.style.setProperty("--accent", accent);
    document.documentElement.style.setProperty("--accent-soft", accentSoft);
  }, []);

  React.useEffect(() => {
    const id = requestAnimationFrame(() => document.body.classList.add("is-loaded"));
    return () => cancelAnimationFrame(id);
  }, []);

  useReveal();

  return (
    <>
      <div className="shell">
        <header className="top reveal">
          <a className="wordmark" href="/" aria-label="Brand Stack — home">
            <div className="wordmark-mark">B</div>
            <span>Brand Stack · The Router</span>
          </a>
          <div className="top-meta">
            <span><span className="dot" /><Counter to={6} /> levers live</span>
            <span>v.2026.05</span>
            <span>est. 2024 · Lisbon</span>
          </div>
        </header>

        <section className="hero">
          <p className="hero-tag reveal">The one-liner</p>
          <HeroH1 />
          <p className="hero-sub reveal" style={{ "--reveal-delay": "700ms" }}>
            <b>Five levers. One question:</b> which one fits your store right now?
            Pick what you need below — or ask the router if you're not sure.
          </p>
          <RouterDiagram hovered={hovered} />
        </section>

        <section className="grid-section">
          <div className="grid-head reveal">
            <h2>The levers</h2>
            <div className="count">
              <b><Counter to={6} /></b> · sorted by what most stores reach for first
            </div>
          </div>
          <div className="grid">
            {LEVERS.map((lever, i) => (
              <div
                key={lever.id}
                className="reveal"
                style={{ "--reveal-delay": `${i * 80}ms` }}
              >
                <LeverCard
                  lever={lever}
                  onHover={setHovered}
                  onLeave={() => setHovered(null)}
                  onSelect={() => {}}
                />
              </div>
            ))}
          </div>
        </section>

        <section className="framing">
          <div className="framing-grid">
            <div className="framing-label reveal">
              <span className="framing-label-num">§</span>
              Why we built it this way
            </div>
            <div className="framing-body reveal" style={{ "--reveal-delay": "150ms" }}>
              <p>
                After working with hundreds of stores, the same growth problems kept
                showing up in the same order. Creative dries up. Catalog drifts. Ops
                lives in a spreadsheet someone's afraid to touch.
              </p>
              <p>
                So we built <em>specialized tools</em> — one per problem — instead of one
                bloated agency selling a retainer. Pick the lever that matches the
                problem you have today. Come back when the next one shows up.
              </p>
            </div>
          </div>
        </section>

        <section className="capture">
          <div className="capture-inner">
            <div className="reveal">
              <p className="capture-sub">№ 07 — out next Tuesday</p>
              <h2 className="capture-title">
                Picked no <em>lever</em> today? Take the letter.
              </h2>
            </div>
            <div className="reveal" style={{ "--reveal-delay": "200ms" }}>
              <form
                className="capture-form"
                onSubmit={(e) => {
                  e.preventDefault();
                  const email = e.currentTarget.email.value;
                  alert(`Thanks — ${email} added to The Drop.`);
                  e.currentTarget.reset();
                }}
              >
                <input name="email" type="email" placeholder="founder@yourstore.com" required />
                <button type="submit">Get The Drop</button>
              </form>
              <p className="capture-fine">Monthly. One operator letter. Unsubscribe in one click.</p>
            </div>
          </div>
        </section>

        <footer className="foot reveal">
          <div>© 2026 Brand Stack</div>
          <div className="foot-links">
            <a href="#">Manifesto</a>
            <a href="#">Press</a>
            <a href="#">Contact</a>
          </div>
        </footer>
      </div>

      <button
        className={`bot-fab${botOpen ? " is-open" : ""}`}
        onClick={() => setBotOpen(true)}
        aria-label="Open router"
      >
        <span className="bot-fab-pulse" />
        Ask the router
      </button>

      <Chatbot open={botOpen} onClose={() => setBotOpen(false)} accent={accent} />
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
