/* Recon Hero Variations — three plays for the splash.
   All three share: terracotta accent, Fraunces display, JetBrains Mono labels,
   ink/paper palette. All three pin to the viewport — no scroll to hook.
   The poetic line ("answers are out there…") survives as a smaller secondary
   in each, never as the lead. SignalGlobe is demoted in A & C, absent in B.
   Each ends in primary CTA (sample) + secondary CTA (preview real PDF). */

const { useState, useEffect, useRef, useMemo } = React;

/* ---------- Shared: Scout mark ---------- */
function ScoutMark({ size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <g fill="currentColor">
        <path d="M 3.5 10.5 C 3.5 8.5, 5 6.5, 7 5.5 C 8.5 4.7, 10 4.3, 12 4.3 C 14 4.3, 15.5 4.7, 17 5.5 C 19 6.5, 20.5 8.5, 20.5 10.5 L 20.5 11 L 3.5 11 Z" />
        <rect x="3" y="10.6" width="18" height="1.6" />
        <rect x="4" y="12.4" width="16" height="4.2" rx="0.6" />
        <path d="M 2 20 C 2 18, 5 17.5, 12 17.5 C 19 17.5, 22 18, 22 20 L 22 24 L 2 24 Z" />
      </g>
      <circle cx="8" cy="14.5" r="1.1" fill="#0A0A0A" />
      <circle cx="16" cy="14.5" r="1.1" fill="#0A0A0A" />
      <circle cx="8" cy="14.5" r="0.55" fill="#C36B3E" />
    </svg>
  );
}

/* ---------- Shared: TopBar (matches prod) ---------- */
function TopBar() {
  return (
    <header className="hv-topbar">
      <a href="/" className="hv-brand">
        <span className="hv-mark"><ScoutMark size={22} /></span>
        <span className="hv-brand-word">Recon<em>.</em></span>
      </a>
      <nav className="hv-topnav">
        <a href="/site/method.html">Method</a>
        <a href="/site/sample.html">Sample</a>
        <a href="/site/pricing.html">Pricing</a>
        <a href="/site/about.html">About</a>
        <a href="/site/faq.html">FAQ</a>
        <a href="/site/signup.html" className="hv-pill">Sign up →</a>
      </nav>
    </header>
  );
}

/* ---------- Shared: SignalGlobe (demoted — smaller, lower opacity) ---------- */
function SignalGlobe({ opacity = 0.35, side = "right" }) {
  const canvasRef = useRef(null);
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    let w, h, dpr;
    function resize() {
      dpr = Math.min(window.devicePixelRatio || 1, 2);
      w = canvas.clientWidth; h = canvas.clientHeight;
      canvas.width = w * dpr; canvas.height = h * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    resize();
    const onR = () => resize();
    window.addEventListener("resize", onR);

    const N = 70;
    const nodes = [];
    for (let i = 0; i < N; i++) {
      const phi = Math.acos(1 - 2 * (i + 0.5) / N);
      const theta = Math.PI * (1 + Math.sqrt(5)) * i;
      nodes.push({
        x: Math.cos(theta) * Math.sin(phi),
        y: Math.sin(theta) * Math.sin(phi),
        z: Math.cos(phi),
        pulse: Math.random() * Math.PI * 2,
        speed: 0.5 + Math.random() * 1.5,
      });
    }

    let raf, t0 = performance.now();
    function tick(t) {
      const dt = (t - t0) / 1000;
      ctx.clearRect(0, 0, w, h);
      const cx = side === "right" ? w * 0.78 : w * 0.22;
      const cy = h * 0.5;
      const R = Math.min(w, h) * 0.38;
      const ay = dt * 0.08;
      const ax = Math.sin(dt * 0.05) * 0.15;

      const projected = nodes.map(n => {
        let x = n.x * Math.cos(ay) + n.z * Math.sin(ay);
        let z = -n.x * Math.sin(ay) + n.z * Math.cos(ay);
        let y = n.y;
        const y2 = y * Math.cos(ax) - z * Math.sin(ax);
        const z2 = y * Math.sin(ax) + z * Math.cos(ax);
        y = y2; z = z2;
        return { px: cx + x * R, py: cy + y * R, z, depth: (z + 1) / 2, n };
      });

      ctx.lineWidth = 1;
      for (let i = 0; i < projected.length; i++) {
        for (let j = i + 1; j < projected.length; j++) {
          const a = projected[i], b = projected[j];
          const dot = a.n.x * b.n.x + a.n.y * b.n.y + a.n.z * b.n.z;
          if (dot < 0.78) continue;
          if (a.z < -0.15 || b.z < -0.15) continue;
          const alpha = Math.min(a.depth, b.depth) * 0.16 * ((dot - 0.78) / 0.22) * opacity;
          if (alpha < 0.02) continue;
          ctx.strokeStyle = `rgba(195, 107, 62, ${alpha})`;
          ctx.beginPath(); ctx.moveTo(a.px, a.py); ctx.lineTo(b.px, b.py); ctx.stroke();
        }
      }
      for (const p of projected) {
        const pulse = 0.5 + 0.5 * Math.sin(p.n.pulse + dt * p.n.speed);
        const r = 0.5 + p.depth * 1.4 + pulse * 0.6;
        const a = (0.22 + p.depth * 0.5) * opacity;
        const hot = pulse > 0.92 && p.depth > 0.6;
        ctx.fillStyle = hot
          ? `rgba(195, 107, 62, ${a})`
          : `rgba(250, 247, 242, ${a * 0.7})`;
        ctx.beginPath(); ctx.arc(p.px, p.py, r, 0, Math.PI * 2); ctx.fill();
      }
      raf = requestAnimationFrame(tick);
    }
    raf = requestAnimationFrame(tick);
    return () => { cancelAnimationFrame(raf); window.removeEventListener("resize", onR); };
  }, [opacity, side]);
  return <canvas ref={canvasRef} className="hv-globe" aria-hidden="true"></canvas>;
}

/* ---------- Shared: CTA cluster ---------- */
function CTACluster({ primary = "Send me a sample", onSecondary }) {
  return (
    <div className="hv-cta-row">
      <a className="hv-cta-primary" href="/site/signup.html"><span>{primary}</span><span className="hv-arrow">→</span></a>
      <button className="hv-cta-secondary" onClick={onSecondary}>
        <span className="hv-cta-secondary-icon" aria-hidden="true">
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
            <rect x="2" y="1" width="9" height="12" rx="1" stroke="currentColor" strokeWidth="1.2" fill="none"/>
            <path d="M4.5 5h4M4.5 7h4M4.5 9h2.5" stroke="currentColor" strokeWidth="1" strokeLinecap="round"/>
          </svg>
        </span>
        <span>See a real (redacted) report</span>
      </button>
    </div>
  );
}

/* ---------- Shared: Sample PDF lightbox ---------- */
function SampleLightbox({ open, onClose }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div className="hv-lightbox" onClick={onClose} role="dialog" aria-modal="true" aria-label="Sample report">
      <div className="hv-lightbox-card" onClick={(e) => e.stopPropagation()}>
        <div className="hv-lightbox-head">
          <span className="hv-lightbox-tag">— Redacted sample · Coffee shop, San Diego · April 2026</span>
          <button className="hv-lightbox-close" onClick={onClose} aria-label="Close">×</button>
        </div>
        <div className="hv-lightbox-body">
          <RedactedReportPage />
          <RedactedReportPage variant={2} />
        </div>
        <div className="hv-lightbox-foot">
          <span>2 of 6 pages shown · names &amp; reviews redacted</span>
          <a className="hv-lightbox-cta" href="/site/sample.html"><span>Read the full sample →</span></a>
        </div>
      </div>
    </div>
  );
}

/* ---------- Shared: Redacted report page (the artifact visual) ---------- */
function RedactedReportPage({ variant = 1, scale = 1 }) {
  // A page mockup — typeset to look like a real report. Used both inside the
  // hero for variants A+B and inside the lightbox.
  const w = 540 * scale;
  const h = 700 * scale;
  return (
    <div className="hv-page" style={{ width: w, height: h }}>
      <div className="hv-page-head">
        <span className="hv-page-num">— {variant === 1 ? "01" : "02"}</span>
        <span className="hv-page-title">
          {variant === 1 ? "Customer signal · ranked" : "Competitor weak spots"}
        </span>
        <span className="hv-page-vol">Illustrative · sample</span>
      </div>
      <div className="hv-page-body">
        {variant === 1 ? (
          <>
            <h4 className="hv-page-h">What's drifting up <em>this month</em></h4>
            <div className="hv-page-rows">
              <div className="hv-page-row">
                <span className="hv-page-row-k">↑ 01</span>
                <span className="hv-page-row-v">"<span className="hv-redact">▮▮▮▮▮▮▮ ▮▮▮ ▮▮▮▮ ▮▮▮▮▮▮▮▮</span>" — 7 reviews mention</span>
              </div>
              <div className="hv-page-row">
                <span className="hv-page-row-k">↑ 02</span>
                <span className="hv-page-row-v">"<span className="hv-redact">▮▮▮▮ ▮▮ ▮▮▮▮▮▮▮▮▮ ▮▮▮▮</span>" — 5 reviews mention</span>
              </div>
              <div className="hv-page-row">
                <span className="hv-page-row-k">↑ 03</span>
                <span className="hv-page-row-v">"<span className="hv-redact">▮▮▮▮▮▮▮ ▮▮▮▮▮▮▮ ▮▮ ▮▮▮▮</span>" — 4 reviews mention</span>
              </div>
            </div>
            <h4 className="hv-page-h" style={{ marginTop: 28 }}>Drifting <em>down</em></h4>
            <div className="hv-page-rows">
              <div className="hv-page-row">
                <span className="hv-page-row-k hv-down">↓ 01</span>
                <span className="hv-page-row-v">"<span className="hv-redact">▮▮▮▮ ▮▮▮▮▮▮▮ ▮▮▮▮ ▮▮▮▮</span>" — down from 11 last month</span>
              </div>
              <div className="hv-page-row">
                <span className="hv-page-row-k hv-down">↓ 02</span>
                <span className="hv-page-row-v">"<span className="hv-redact">▮▮▮▮▮▮▮▮ ▮▮▮ ▮▮▮▮▮▮▮▮▮</span>" — down from 6 last month</span>
              </div>
            </div>
            <div className="hv-page-pull">
              <span className="hv-pull-mark">¶</span>
              <p>The <em>weekend morning</em> staffing complaint isn't going away. It's changed shape — last month it was speed, this month it's warmth. Same root cause.</p>
            </div>
          </>
        ) : (
          <>
            <h4 className="hv-page-h">Where the <em>three closest</em> are leaking</h4>
            <div className="hv-page-comp">
              <div className="hv-page-comp-row">
                <span className="hv-page-comp-name"><span className="hv-redact">▮▮▮▮▮▮▮▮▮ ▮▮▮▮▮▮</span></span>
                <span className="hv-page-comp-bar"><span style={{ width: "78%" }}></span></span>
                <span className="hv-page-comp-tag">— inconsistent espresso</span>
              </div>
              <div className="hv-page-comp-row">
                <span className="hv-page-comp-name"><span className="hv-redact">▮▮▮ ▮▮▮▮ ▮▮▮▮▮▮▮▮</span></span>
                <span className="hv-page-comp-bar"><span style={{ width: "62%" }}></span></span>
                <span className="hv-page-comp-tag">— rude staff (Sat AM)</span>
              </div>
              <div className="hv-page-comp-row">
                <span className="hv-page-comp-name"><span className="hv-redact">▮▮▮▮▮ ▮▮▮▮▮▮ ▮▮.</span></span>
                <span className="hv-page-comp-bar"><span style={{ width: "44%" }}></span></span>
                <span className="hv-page-comp-tag">— pour-over wait time</span>
              </div>
            </div>
            <div className="hv-page-pull">
              <span className="hv-pull-mark">¶</span>
              <p>Their <em>Saturday-morning</em> staffing problem is your <em>Saturday-morning</em> opportunity. Two of three competitors are weak on the same shift you're winning on.</p>
            </div>
            <div className="hv-page-rows" style={{ marginTop: 18 }}>
              <div className="hv-page-row">
                <span className="hv-page-row-k">→</span>
                <span className="hv-page-row-v">Sample excerpt: "<span className="hv-redact">▮▮▮▮▮▮▮ ▮▮▮▮▮ ▮▮▮▮▮ ▮▮▮▮▮▮▮▮ ▮▮ ▮▮▮▮ ▮▮▮▮▮▮▮▮</span>"</span>
              </div>
              <div className="hv-page-row">
                <span className="hv-page-row-k">→</span>
                <span className="hv-page-row-v">Sample excerpt: "<span className="hv-redact">▮▮▮▮▮▮ ▮▮ ▮▮▮▮▮ ▮▮▮▮▮▮▮▮▮ ▮▮▮ ▮▮▮▮▮▮▮▮▮</span>"</span>
              </div>
            </div>
          </>
        )}
      </div>
      <div className="hv-page-foot">
        <span>Recon · Illustrative</span>
        <span>page {variant === 1 ? "02" : "03"} / 06</span>
      </div>
    </div>
  );
}

/* ---------- Shared: MethodBlip ----------
   The "how we scan" blip — one line under any hero's visual, sourced and
   verifiable. Lifted out of hero-g so future heroes can import it. */
function MethodBlip() {
  const sources = [
    "Google", "Yelp", "TripAdvisor",
    "Reddit", "X", "YouTube", "Hacker News", "Bluesky", "TikTok", "Instagram",
    "Niche forums", "Industry threads",
  ];
  return (
    <div className="hv-method">
      <div className="hv-method-icon" aria-hidden="true">
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <circle cx="6" cy="6" r="4" stroke="currentColor" strokeWidth="1.2" fill="none"/>
          <line x1="9" y1="9" x2="12" y2="12" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/>
        </svg>
      </div>
      <div className="hv-method-body">
        <span className="hv-method-tag">— How we scan</span>
        <p>
          Twelve public sources, ranked by relevance to <em>your</em> goals.
          No login. No customer data. Just the open web, read carefully.
        </p>
        <ul className="hv-method-chips">
          {sources.map(s => <li key={s}>{s}</li>)}
        </ul>
      </div>
      <a className="hv-method-link" href="/site/method.html">
        <span>The method</span>
        <span className="hv-arrow">→</span>
      </a>
    </div>
  );
}

Object.assign(window, { ScoutMark, TopBar, SignalGlobe, CTACluster, SampleLightbox, RedactedReportPage, MethodBlip });
