// ==== App root =======================================================

const SECTIONS = [
  { id: "hero",        label: "Intro" },
  { id: "about",       label: "About" },
  { id: "graph",       label: "Atlas" },
  { id: "projects",    label: "Work" },
  { id: "mantis",      label: "MANTIS" },
  { id: "trifecta",    label: "Lethal Trifecta" },
  { id: "mcp",         label: "MCP Gateway" },
  { id: "soc",         label: "Live SOC" },
  { id: "owasp",       label: "Threat Model" },
  { id: "timeline",    label: "Timeline" },
  { id: "research",    label: "Research" },
  { id: "recognition", label: "Talks & Awards" },
  { id: "skills",      label: "Stack" },
  { id: "writing",     label: "Writing" },
  { id: "now",         label: "Now" },
  { id: "contact",     label: "Contact" },
];

function App() {
  const active = useActiveSection(SECTIONS.map(s => s.id));

  // Cinematic mode: reveal each scene as it enters viewport.
  useEffect(() => {
    const scenes = document.querySelectorAll(".scene");
    const io = new IntersectionObserver(entries => {
      for (const e of entries) {
        if (e.isIntersecting) e.target.classList.add("in-view");
        // Optional re-trigger on exit. Disabled — once revealed, stays revealed.
      }
    }, { threshold: 0, rootMargin: "0px 0px -5% 0px" });
    scenes.forEach(s => io.observe(s));

    // Hero — give boot a beat then cascade in
    const hero = document.getElementById("hero");
    if (hero) {
      const t = setTimeout(() => hero.classList.add("boot-done"), 1200);
      // earlier if boot is already dismissed
      const i = setInterval(() => { if (!document.getElementById("boot")) { hero.classList.add("boot-done"); clearInterval(i); } }, 150);
      return () => { io.disconnect(); clearTimeout(t); clearInterval(i); };
    }
    return () => io.disconnect();
  }, []);

  // Scroll progress bar + dock fade-in past hero
  useEffect(() => {
    const fill = document.querySelector("#scroll-progress .fill");
    const dock = document.querySelector(".os-dock");
    if (!fill) return;
    function update() {
      const max = (document.documentElement.scrollHeight - window.innerHeight) || 1;
      const y = window.scrollY;
      const p = Math.min(1, Math.max(0, y / max));
      fill.style.transform = `scaleX(${p})`;
      if (dock) {
        // Show dock once user has scrolled past the hero (60% of first viewport)
        if (y > window.innerHeight * 0.6) dock.classList.add("visible");
        else dock.classList.remove("visible");
      }
    }
    update();
    window.addEventListener("scroll", update, { passive: true });
    window.addEventListener("resize", update);
    return () => { window.removeEventListener("scroll", update); window.removeEventListener("resize", update); };
  }, []);

  return (
    <div className="os-shell">
      <OSTopBar />
      <div id="scroll-progress"><div className="fill" /></div>
      <OSRail active={active} sections={SECTIONS} />
      <OSDock active={active} sections={SECTIONS} />

      <Hero />
      <About />
      <ForceGraph />
      <Projects />
      <Mantis />
      <Trifecta />
      <McpGateway />
      <SocSim />
      <Owasp />
      <CareerTimeline />
      <Research />
      <TalksAwards />
      <Skills />
      <Writing />
      <Now />
      <Contact />

      <EasterEggs />
    </div>
  );
}

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

// Kickoff Three.js background scene independently of React lifecycle.
// Defer until next paint AND ensure boot has had a chance to load.
setTimeout(() => {
  try {
    const r = window.initBackgroundScene && window.initBackgroundScene();
    console.log("bg scene init:", !!r, "canvas:", document.getElementById("bg-canvas").width);
  } catch (e) { console.warn("bg scene init failed:", e); }
}, 100);
