/* global React, ReactDOM,
   Nav, ChapterRail, Hero, Manifesto, Numbers, AreasHorizontal, AreasNameMarquee,
   Locations, Partners, Analyses, Cta, Footer, ModeToggle, Topbar */

const { useEffect, useState } = React;

// All reveal animations are CSS-only now (no observer needed)
function useReveal() { /* no-op */ }

// Chapter detector — reads which screen-label is most visible
function useCurrentSection() {
  const [section, setSection] = useState("Hero");
  useEffect(() => {
    const sections = Array.from(document.querySelectorAll("[data-screen-label]"));
    if (!sections.length) return;
    const onScroll = () => {
      const vh = window.innerHeight;
      let best = "Hero";
      let bestScore = -Infinity;
      sections.forEach(s => {
        const r = s.getBoundingClientRect();
        // Score: how much of section is in upper-mid viewport
        const top = r.top;
        const bottom = r.bottom;
        if (bottom < 100 || top > vh - 100) return;
        // section that is closest to top of view
        const score = -Math.abs(top - vh * 0.25);
        if (score > bestScore) {
          bestScore = score;
          best = s.dataset.screenLabel;
        }
      });
      setSection(best);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return section;
}

function App() {
  useReveal();
  const section = useCurrentSection();
  const [mode, setModeState] = useState(() =>
    (typeof localStorage !== "undefined" && localStorage.getItem("mmt-mode")) || "moderno"
  );
  const setMode = (m) => {
    setModeState(m);
    try { localStorage.setItem("mmt-mode", m); } catch (e) {}
  };
  useEffect(() => {
    document.body.dataset.mode = mode;
  }, [mode]);
  // Hash scroll: React render runs after the browser resolves the URL hash,
  // so #socios etc. land at scrollY=0. Retry across paint cycles because
  // images / reveal animations keep shifting layout for ~1s after mount.
  useEffect(() => {
    const scrollToHash = () => {
      const h = window.location.hash;
      if (!h || h.length < 2) return;
      const id = h.slice(1);
      const attempt = () => {
        const el = document.getElementById(id);
        if (!el) return;
        // Three strategies because scroll container varies with mode/CSS:
        // (a) scrollIntoView is the spec API.
        // (b) scrollingElement.scrollTop covers html/body cases.
        // (c) window.scrollTo is the fallback for visible-overflow roots.
        try { el.scrollIntoView({ behavior: "instant", block: "start" }); } catch (e) {
          try { el.scrollIntoView(true); } catch (_) {}
        }
        const scroller = document.scrollingElement || document.body;
        const y = el.getBoundingClientRect().top + scroller.scrollTop;
        scroller.scrollTop = y;
        window.scrollTo(0, y);
      };
      // Multiple attempts: images, fonts and reveal animations resize content.
      [50, 250, 600, 1200].forEach(ms => setTimeout(attempt, ms));
    };
    scrollToHash();
    window.addEventListener("hashchange", scrollToHash);
    return () => window.removeEventListener("hashchange", scrollToHash);
  }, []);
  return (
    <React.Fragment>
      <Nav mode={mode} setMode={setMode} />
      <ChapterRail section={section} />
      <main>
        <AreasNameMarquee />
        <Hero />
        <Manifesto />
        <Numbers />
        <AreasHorizontal />
        <Locations />
        <Partners />
        <Analyses />
        <Cta />
      </main>
      <Footer />
    </React.Fragment>
  );
}

class ErrorBoundary extends React.Component {
  constructor(props) { super(props); this.state = { err: null }; }
  static getDerivedStateFromError(e) { return { err: String(e) }; }
  render() {
    if (this.state.err) return <pre style={{padding:40,color:'red',whiteSpace:'pre-wrap'}}>{this.state.err}</pre>;
    return this.props.children;
  }
}

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