/* App — Herr Müller und sein Chauffeur */
const { useState: useStateA, useEffect: useEffectA, useCallback: useCallbackA } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#d6249e",
  "headline": "loud",
  "background": "schwarz",
  "motion": true,
  "grain": true
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [lb, setLb] = useStateA(null);

  /* apply tweaks to document */
  useEffectA(() => {
    const root = document.documentElement;
    root.style.setProperty("--accent", t.accent);
    document.body.classList.toggle("head-poetic", t.headline === "poetisch");
    document.body.classList.toggle("bg-blue", t.background === "blau");
    document.body.classList.toggle("motion-off", !t.motion);
    document.body.classList.toggle("grain-off", !t.grain);
  }, [t]);

  /* reveal on scroll — rect driven; first pass deferred to a double rAF so the
     0→1 opacity transition gets a real start frame (else above-the-fold
     elements add `.in` in the same recalc as creation and stick at opacity 0) */
  useEffectA(() => {
    const els = Array.from(document.querySelectorAll("[data-reveal]"));
    if (!t.motion) { els.forEach((e) => e.classList.add("in")); return; }
    const reveal = () => {
      const h = window.innerHeight || document.documentElement.clientHeight;
      els.forEach((e) => {
        if (e.classList.contains("in")) return;
        const r = e.getBoundingClientRect();
        if (r.top < h * 0.92 && r.bottom > 0) e.classList.add("in");
      });
    };
    let raf2 = 0;
    const raf1 = requestAnimationFrame(() => { raf2 = requestAnimationFrame(reveal); });
    window.addEventListener("scroll", reveal, { passive: true });
    window.addEventListener("resize", reveal);
    // safety net: force any still-hidden element fully visible WITHOUT a
    // transition (a bare classList.add('in') would no-op on a stuck element)
    const safety = setTimeout(() => {
      els.forEach((e) => { e.classList.add("in", "reveal-instant"); });
    }, 2200);
    return () => {
      cancelAnimationFrame(raf1);
      cancelAnimationFrame(raf2);
      clearTimeout(safety);
      window.removeEventListener("scroll", reveal);
      window.removeEventListener("resize", reveal);
    };
  }, [t.motion]);

  const openLb = useCallbackA((i) => setLb(i), []);
  const navLb = useCallbackA((d) => setLb((cur) => {
    if (cur === null) return cur;
    const n = GALLERY.length;
    return (cur + d + n) % n;
  }), []);

  return (
    <>
      <Nav />
      <main>
        <Hero />
        <Marquee />
        <About />
        <Music />
        <Videos />
        <Press />
        <Gallery onOpen={openLb} />
        <Contact />
      </main>
      <Footer />
      <Lightbox index={lb} onClose={() => setLb(null)} onNav={navLb} />

      <TweaksPanel>
        <TweakSection label="Farbe" />
        <TweakColor label="Akzent" value={t.accent}
          options={["#d6249e", "#d98a24", "#4aa3d6", "#8a5cf0"]}
          onChange={(v) => setTweak("accent", v)} />
        <TweakRadio label="Hintergrund" value={t.background}
          options={["schwarz", "blau"]}
          onChange={(v) => setTweak("background", v)} />
        <TweakSection label="Typografie" />
        <TweakRadio label="Headlines" value={t.headline}
          options={["loud", "poetisch"]}
          onChange={(v) => setTweak("headline", v)} />
        <TweakSection label="Atmosphäre" />
        <TweakToggle label="Bewegung" value={t.motion}
          onChange={(v) => setTweak("motion", v)} />
        <TweakToggle label="Filmkorn" value={t.grain}
          onChange={(v) => setTweak("grain", v)} />
      </TweaksPanel>
    </>
  );
}

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