/* roastynote v3 — app root */
const { useState, useEffect } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "paperTone": "cream",
  "darkTone": "ink",
  "accent": "ember",
  "wordmark": "split",
  "displayScale": 1
}/*EDITMODE-END*/;

const PAPER = { cream: "#F4EFE6", shell: "#EBE4D6", bone: "#DED6C6" };
const DARK  = { ink: "#14110D", espresso: "#221913", roast: "#2E1C10" };
const ACCENT = { ember: "#952C16", ochre: "#9C7A33", clay: "#B96A45" };

function useReveal() {
  useEffect(() => {
    const check = () => {
      const vh = window.innerHeight;
      document.querySelectorAll("[data-reveal]:not(.in)").forEach((el) => {
        const r = el.getBoundingClientRect();
        if (r.top < vh * 0.9 && r.bottom > 0) el.classList.add("in");
      });
    };
    check();
    const t1 = setTimeout(check, 80);
    const t2 = setTimeout(check, 400);
    window.addEventListener("scroll", check, { passive: true });
    window.addEventListener("resize", check, { passive: true });
    return () => {
      clearTimeout(t1); clearTimeout(t2);
      window.removeEventListener("scroll", check);
      window.removeEventListener("resize", check);
    };
  }, []);
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [lang, setLangState] = useState(() => {
    try { return localStorage.getItem("rn-lang") || "en"; } catch (e) { return "en"; }
  });
  const setLang = (v) => {
    setLangState(v);
    try { localStorage.setItem("rn-lang", v); } catch (e) {}
  };
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const [openRoom, setOpenRoom] = useState(-1);

  useEffect(() => {
    const r = document.documentElement.style;
    r.setProperty("--rn-paper", PAPER[t.paperTone] || PAPER.cream);
    r.setProperty("--rn-dark", DARK[t.darkTone] || DARK.ink);
    r.setProperty("--rn-accent", ACCENT[t.accent] || ACCENT.ember);
    r.setProperty("--rn-display-scale", String(t.displayScale ?? 1));
  }, [t.paperTone, t.darkTone, t.accent, t.displayScale]);

  useEffect(() => {
    document.body.setAttribute("data-wordmark", t.wordmark || "split");
  }, [t.wordmark]);

  useEffect(() => {
    document.documentElement.lang = lang === "jp" ? "ja" : "en";
    document.body.classList.toggle("jp", lang === "jp");
  }, [lang]);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 48);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
  }, [menuOpen]);

  useReveal();

  const C = window.RN_CONTENT;

  return (
    <React.Fragment>
      <Nav lang={lang} setLang={setLang} scrolled={scrolled} onOpenMenu={() => setMenuOpen(true)} />
      <MobileMenu lang={lang} setLang={setLang} open={menuOpen} onClose={() => setMenuOpen(false)} />

      <main>
        <Hero lang={lang} />
        <Marquee lang={lang} key={"mq-" + lang} />
        <Thesis lang={lang} />
        <ImageBreak src="assets/img/thesis.jpg"
          captionLeft={T(C.interlude.caption, lang)}
          captionRight={T(C.interlude.coord, lang)} />
        <Rooms lang={lang} openRoom={openRoom} setOpenRoom={setOpenRoom} />
        <Approach lang={lang} />
        <SelectedWork lang={lang} />
        <Journal lang={lang} />
        <PullQuote lang={lang} />
      </main>

      <Footer lang={lang} />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Type" />
        <TweakRadio label="Wordmark" value={t.wordmark}
          options={["split", "serif", "grotesk"]}
          onChange={(v) => setTweak("wordmark", v)} />
        <TweakSlider label="Display scale" value={t.displayScale} min={0.8} max={1.25} step={0.01}
          onChange={(v) => setTweak("displayScale", v)} />
        <TweakSection label="Palette" />
        <TweakColor label="Paper" value={PAPER[t.paperTone]}
          options={[PAPER.cream, PAPER.shell, PAPER.bone]}
          onChange={(v) => setTweak("paperTone", keyOfV3(PAPER, v))} />
        <TweakColor label="Dark sections" value={DARK[t.darkTone]}
          options={[DARK.ink, DARK.espresso, DARK.roast]}
          onChange={(v) => setTweak("darkTone", keyOfV3(DARK, v))} />
        <TweakColor label="Accent" value={ACCENT[t.accent]}
          options={[ACCENT.ember, ACCENT.ochre, ACCENT.clay]}
          onChange={(v) => setTweak("accent", keyOfV3(ACCENT, v))} />
      </TweaksPanel>
    </React.Fragment>
  );
}

function keyOfV3(map, val) {
  return Object.keys(map).find(k => map[k] === val) || Object.keys(map)[0];
}

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