/* ByteSiege landing — swappable hero components + adaptive nav.
   Depends on: Icon, HeroMock, Donut (from sections.jsx). */

function SiteNav({ dark }) {
  const [scrolled, setScrolled] = React.useState(false);
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 12);
    window.addEventListener("scroll", onScroll); onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  const close = () => setOpen(false);
  const burger = open
    ? (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="6" y1="6" x2="18" y2="18"></line><line x1="18" y1="6" x2="6" y2="18"></line></svg>)
    : (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="3" y1="7" x2="21" y2="7"></line><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="17" x2="21" y2="17"></line></svg>);
  return (
    <nav className={"lp-nav" + (scrolled ? " scrolled" : "") + (dark ? " over-dark" : "") + (open ? " menu-open" : "")}>
      <div className="nav-inner">
        <img className="logo" src="assets/logo.svg" alt="ByteSiege" />
        <img className="logo-rev" src="assets/logo-reversed.svg" alt="ByteSiege" />
        <div className="nav-links">
          <a href="#platform">Platform</a>
          <a href="#validate">Validation</a>
          <a href="#drp">Digital risk</a>
          <a href="#how">How CTEM works</a>
        </div>
        <div className="nav-spacer"></div>
        <div className="nav-cta">
          <a href="#" className="btn btn-secondary nav-signin" style={{ fontSize: "14px", padding: "9px 16px" }}>Sign in</a>
          <a href="start-free-assessment.html" className="btn btn-accent" style={{ padding: "10px 18px", fontSize: "14px" }}>Start free assessment</a>
        </div>
        <button className="nav-burger" aria-label="Menu" aria-expanded={open} onClick={() => setOpen((o) => !o)}>{burger}</button>
      </div>
      <div className="nav-menu" hidden={!open}>
        <a href="#platform" onClick={close}>Platform</a>
        <a href="#validate" onClick={close}>Validation</a>
        <a href="#drp" onClick={close}>Digital risk</a>
        <a href="#how" onClick={close}>How CTEM works</a>
        <div className="nav-menu-cta">
          <a href="#" className="btn btn-secondary" onClick={close}>Sign in</a>
          <a href="start-free-assessment.html" className="btn btn-accent" onClick={close}>Start free assessment</a>
        </div>
      </div>
    </nav>
  );
}

/* ---- full-bleed network banner (force-directed ASM graph, projected onto a spherical cap) ---- */
// Subtle parallax: the hero backdrop drifts at a fraction of scroll speed (a gentle
// lag, not a hard pin). strength 0 = scrolls normally, 1 = fully fixed. Degrades to
// static if scroll events don't fire — never breaks.
function useParallax(strength) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    const el = ref.current;
    if (!el) return;
    let raf = 0;
    const apply = () => {
      raf = 0;
      const y = Math.min(Math.max(window.scrollY || window.pageYOffset || 0, 0), 900);
      el.style.transform = `translate3d(0, ${(y * strength).toFixed(1)}px, 0)`;
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(apply); };
    apply();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => { window.removeEventListener("scroll", onScroll); if (raf) cancelAnimationFrame(raf); };
  }, [strength]);
  return ref;
}
function NetNode({ n }) {
  const { x, y, r, shape, cls, sev, op } = n;
  let inner;
  if (shape === "hub") inner = (<g><circle className="n-hub" cx={x} cy={y} r={r}></circle><circle cx={x} cy={y} r={r * 0.42} fill="#07182B"></circle></g>);
  else if (shape === "rect") inner = (<rect className={cls} x={x - r} y={y - r} width={r * 2} height={r * 2} rx="1.6"></rect>);
  else if (shape === "diamond") inner = (<path className={cls + (sev ? " " + sev : "")} d={`M${x} ${y - r} L${x + r} ${y} L${x} ${y + r} L${x - r} ${y} Z`}></path>);
  else inner = (<circle className={cls} cx={x} cy={y} r={r}></circle>);
  return <g style={{ opacity: op }}>{inner}</g>;
}
function NetGraph() {
  const g = (typeof window !== "undefined" && window.NETGRAPH) || { nodes: [], edges: [], flows: [], grid: [] };
  const glows = g.nodes.filter((n) => n.glow);
  // Progressive zoom: as the viewport narrows we interpolate the viewBox from the
  // full graph (desktop) to a tight focal window (phone). A smaller viewBox = larger
  // nodes; panning the focal up-left lets the dense cluster bleed off toward the
  // bottom-right, so the phone frames the top-left region with the hub peeking in.
  const FULL = { x: 0, y: 0, w: 1200, h: 560 };
  const ZOOM = { x: 560, y: 96, w: 470, h: 430 }; // focal window over the hub / upper-left cluster
  const computeVB = (w) => {
    const t = Math.max(0, Math.min(1, (900 - w) / (900 - 420))); // 0 desktop → 1 narrow phone
    const e = t * t * (3 - 2 * t); // smoothstep
    const x = FULL.x + (ZOOM.x - FULL.x) * e;
    const y = FULL.y + (ZOOM.y - FULL.y) * e;
    const ww = FULL.w + (ZOOM.w - FULL.w) * e;
    const hh = FULL.h + (ZOOM.h - FULL.h) * e;
    return `${x.toFixed(1)} ${y.toFixed(1)} ${ww.toFixed(1)} ${hh.toFixed(1)}`;
  };
  const [vb, setVb] = React.useState(() => computeVB(typeof window !== "undefined" ? window.innerWidth : 1280));
  React.useEffect(() => {
    const onResize = () => setVb(computeVB(window.innerWidth));
    onResize();
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, []);
  const pxRef = useParallax(0.3);
  return (
    <div className="netpx" ref={pxRef}>
    <svg className="netviz" viewBox={vb} preserveAspectRatio="xMidYMid slice" aria-hidden="true">
      <defs><radialGradient id="netGlow" cx="79%" cy="52%" r="42%"><stop offset="0" stopColor="#20C4E0" stopOpacity=".22"></stop><stop offset="60%" stopColor="#20C4E0" stopOpacity="0"></stop></radialGradient></defs>
      <rect width="1200" height="560" fill="url(#netGlow)"></rect>
      <g>{(g.grid || []).map((ln, i) => <path key={i} className={"sphere-line " + ln.cls} d={ln.d}></path>)}</g>
      <g>{g.edges.map((e, i) => <path key={i} className={"net-edge" + (e.key ? " key" : "")} style={{ opacity: e.op }} d={e.d}></path>)}</g>
      <g>{glows.map((n, i) => <circle key={i} className={"net-glow g" + ((i % 4) + 1)} cx={n.x} cy={n.y} r={n.r} fill="#20C4E0"></circle>)}</g>
      <g>{g.nodes.map((n, i) => <NetNode key={i} n={n} />)}</g>
      <g>{g.flows.map((f, i) => <g key={i} style={{ opacity: f.op }}><circle className="pkt" r={f.r} style={{ offsetPath: `path('${f.d}')`, animationDuration: f.dur + "s", animationDelay: f.delay + "s" }}></circle></g>)}</g>
    </svg>
    </div>
  );
}
function HeroC() {
  return (
    <header className="lp-hero dark hC">
      <div className="hc-bg">
        <div className="aurora"><b className="a1"></b><b className="a2"></b><b className="a3"></b></div>
        <div className="grain"></div>
        <NetGraph />
        <div className="scrim"></div>
      </div>
      <div className="inner">
        <div className="box">
          <h1>Know which exposures attackers can <span className="h-accent">actually exploit.</span></h1>
          <p className="sub">ByteSiege runs a continuous threat exposure management program across your perimeter and brand: discovering exposures, validating what's truly exploitable, and mobilizing the fix.</p>
          <div className="hero-cta">
            <a href="start-free-assessment.html" className="btn btn-accent btn-lg"><Icon name="radar" cls="ic" />Validate my exposures</a>
            <a href="#" className="btn btn-ghost-dark btn-lg"><Icon name="calendar" cls="ic-18" />Book a demo</a>
          </div>
        </div>
      </div>
    </header>
  );
}

const HEROES = {
  C: { label: "Network (full-bleed)", Comp: HeroC },
};

Object.assign(window, { SiteNav, HeroC, HEROES });
