/* global React, ReactDOM, Header, Footer, Home, About, Reps, TakeAction, Contact,
          TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakColor, TweakSelect, TweakToggle,
          AccentPicker */
const { useState: useStateApp, useEffect: useEffectApp, useMemo: useMemoApp } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "navy": "#0a1733",
  "red": "#B0111C",
  "background": "#faf9f5",
  "displayFont": "Libre Franklin",
  "bodyFont": "Public Sans",
  "density": "comfortable",
  "showStripes": true,
  "videoBackgrounds": true
}/*EDITMODE-END*/;

const FONT_OPTIONS_DISPLAY = [
  "Libre Franklin",
  "Domine",
  "DM Serif Display",
  "Archivo",
  "Space Grotesk",
];
const FONT_OPTIONS_BODY = [
  "Public Sans",
  "IBM Plex Sans",
  "Source Sans 3",
  "Inter",
];

function App() {
  const [route, setRoute] = useStateApp(() => {
    const h = window.location.hash.replace("#", "");
    return ["home", "about", "reps", "action", "contact"].includes(h) ? h : "home";
  });
  const [lang, setLang] = useStateApp("en");
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // sync route to hash
  useEffectApp(() => {
    window.location.hash = route;
  }, [route]);

  // listen for back/forward
  useEffectApp(() => {
    const onHash = () => {
      const h = window.location.hash.replace("#", "");
      if (["home", "about", "reps", "action", "contact"].includes(h)) setRoute(h);
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  // apply tweaks to root style
  useEffectApp(() => {
    const r = document.documentElement;
    r.style.setProperty("--navy-900", t.navy);
    r.style.setProperty("--navy-950", shade(t.navy, -8));
    r.style.setProperty("--navy-800", shade(t.navy, 4));
    r.style.setProperty("--navy-700", shade(t.navy, 12));
    // Accent color is now owned by the AccentPicker widget which writes
    // --accent-main/--accent-hover/--accent-on-dark. The dev TweaksPanel's
    // legacy --red setter is intentionally not wired so the picker is the
    // single source of truth for accent. (The "Accent red" control below
    // still appears in the dev panel but is a no-op.)
    r.style.setProperty("--off-white", t.background);
    r.style.setProperty("--font-display", `"${t.displayFont}", "Helvetica Neue", Arial, sans-serif`);
    r.style.setProperty("--font-body", `"${t.bodyFont}", "Helvetica Neue", Arial, sans-serif`);
    document.body.dataset.density = t.density;
    document.body.dataset.stripes = t.showStripes ? "on" : "off";
    document.body.dataset.videos = t.videoBackgrounds ? "on" : "off";
  }, [t]);

  // load fonts dynamically
  useEffectApp(() => {
    const families = [t.displayFont, t.bodyFont].filter(Boolean);
    const url = `https://fonts.googleapis.com/css2?${families.map(f =>
      `family=${f.replace(/\s+/g, "+")}:wght@400;500;600;700;800`
    ).join("&")}&display=swap`;
    let link = document.getElementById("dyn-fonts");
    if (!link) {
      link = document.createElement("link");
      link.id = "dyn-fonts";
      link.rel = "stylesheet";
      document.head.appendChild(link);
    }
    link.href = url;
  }, [t.displayFont, t.bodyFont]);

  const Page = useMemoApp(() => ({
    home: <Home lang={lang} setRoute={setRoute} />,
    about: <About lang={lang} />,
    reps: <Reps lang={lang} />,
    action: <TakeAction lang={lang} />,
    contact: <Contact lang={lang} />,
  })[route] || <Home lang={lang} setRoute={setRoute} />, [route, lang]);

  return (
    <>
      <Header route={route} setRoute={setRoute} lang={lang} setLang={setLang} />
      <main id="main" data-screen-label={route}>
        {Page}
      </main>
      <Footer lang={lang} setRoute={setRoute} />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Brand">
          <TweakColor
            label="Primary navy"
            value={t.navy}
            onChange={v => setTweak("navy", v)}
            options={["#0a1733", "#0e2148", "#1a2b4d", "#152042"]}
          />
          <TweakColor
            label="Accent red"
            value={t.red}
            onChange={v => setTweak("red", v)}
            options={["#B0111C", "#E81B23", "#800810", "#c8102e"]}
          />
          <TweakColor
            label="Page background"
            value={t.background}
            onChange={v => setTweak("background", v)}
            options={["#faf9f5", "#ffffff", "#f4f2eb", "#f6f7fb"]}
          />
        </TweakSection>

        <TweakSection label="Type">
          <TweakSelect
            label="Display font"
            value={t.displayFont}
            options={FONT_OPTIONS_DISPLAY}
            onChange={v => setTweak("displayFont", v)}
          />
          <TweakSelect
            label="Body font"
            value={t.bodyFont}
            options={FONT_OPTIONS_BODY}
            onChange={v => setTweak("bodyFont", v)}
          />
        </TweakSection>

        <TweakSection label="Density & motifs">
          <TweakRadio
            label="Density"
            value={t.density}
            options={["compact", "comfortable", "spacious"]}
            onChange={v => setTweak("density", v)}
          />
          <TweakToggle
            label="Flag stripe motifs"
            value={t.showStripes}
            onChange={v => setTweak("showStripes", v)}
          />
          <TweakToggle
            label="Animated video backgrounds"
            value={t.videoBackgrounds}
            onChange={v => setTweak("videoBackgrounds", v)}
          />
        </TweakSection>
      </TweaksPanel>

      <AccentPicker />
    </>
  );
}

// Slight color shifter for navy variants
function shade(hex, pct) {
  const n = hex.replace("#", "");
  const r = Math.max(0, Math.min(255, parseInt(n.slice(0,2), 16) + Math.round(pct * 2.55)));
  const g = Math.max(0, Math.min(255, parseInt(n.slice(2,4), 16) + Math.round(pct * 2.55)));
  const b = Math.max(0, Math.min(255, parseInt(n.slice(4,6), 16) + Math.round(pct * 2.55)));
  return "#" + [r,g,b].map(x => x.toString(16).padStart(2, "0")).join("");
}

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