/* app.jsx — assembles the site, scroll reveal + scrollspy, Tweaks panel */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "heroStyle": "gallery",
  "motion": "expressive",
  "accent": ["#D63A1A", "#A8281A"],
  "motif": "present"
}/*EDITMODE-END*/;

// ---- scroll reveal: one observer for all .reveal elements ----
function useScrollReveal(active) {
  React.useEffect(() => {
    const els = Array.from(document.querySelectorAll(".reveal:not(.in)"));
    if (!active) { els.forEach((e) => e.classList.add("in")); return; }
    if (!("IntersectionObserver" in window)) { els.forEach((e) => e.classList.add("in")); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((en) => {
        if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); }
      });
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    els.forEach((e) => io.observe(e));
    return () => io.disconnect();
  });
}

// ---- scrollspy for active nav link ----
function useScrollSpy() {
  const [active, setActive] = React.useState("home");
  React.useEffect(() => {
    const ids = ["home", "about", "art", "speaking", "consulting", "contact"];
    const secs = ids.map((id) => document.getElementById(id)).filter(Boolean);
    const io = new IntersectionObserver((entries) => {
      entries.forEach((en) => { if (en.isIntersecting) setActive(en.target.id); });
    }, { rootMargin: "-45% 0px -50% 0px" });
    secs.forEach((s) => io.observe(s));
    return () => io.disconnect();
  }, []);
  return active;
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const active = useScrollSpy();
  const contactRef = React.useRef(null);

  useScrollReveal(t.motion !== "minimal");

  // apply accent + body data attrs
  React.useEffect(() => {
    const root = document.documentElement;
    const a = Array.isArray(t.accent) ? t.accent : [t.accent, t.accent];
    root.style.setProperty("--accent", a[0]);
    root.style.setProperty("--accent-deep", a[1] || a[0]);
    document.body.dataset.motion = t.motion;
    document.body.dataset.motif = t.motif;
  }, [t.accent, t.motion, t.motif]);

  const presetContact = (interest) => {
    if (contactRef.current) contactRef.current.preset(interest);
    const el = document.getElementById("contact");
    if (el) window.scrollTo({ top: el.offsetTop - 60, behavior: t.motion === "minimal" ? "auto" : "smooth" });
  };

  return (
    <React.Fragment>
      <Nav active={active} />
      <main>
        <Hero styleMode={t.heroStyle} motion={t.motion} />
        <Intro />
        <DotworkDivider />
        <About />
        <Art />
        <Speaking onInvite={() => presetContact("Inviting Aditi to speak")} />
        <Consulting onWork={() => presetContact("Consulting & advisory")} />
        <Contact presetRef={contactRef} />
      </main>
      <Footer />

      <TweaksPanel>
        <TweakSection label="Hero" />
        <TweakRadio label="Hero style" value={t.heroStyle}
          options={["gallery", "framed"]}
          onChange={(v) => setTweak("heroStyle", v)} />

        <TweakSection label="Feel" />
        <TweakRadio label="Motion" value={t.motion}
          options={["minimal", "subtle", "expressive"]}
          onChange={(v) => setTweak("motion", v)} />
        <TweakRadio label="Heritage motif" value={t.motif}
          options={["whisper", "present"]}
          onChange={(v) => setTweak("motif", v)} />

        <TweakSection label="Accent colour" />
        <TweakColor label="Accent" value={t.accent}
          options={[["#D63A1A", "#A8281A"], ["#C67C0F", "#A6532A"], ["#0F7B78", "#0A5754"], ["#45233F", "#6A3A60"]]}
          onChange={(v) => setTweak("accent", v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

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