/* app.jsx — router, theme, command palette, tweaks */
(function () {
  const { useState, useEffect, useCallback } = React;
  const {
    Navbar, Footer, Home, RecipesIndex, RecipeDetail, SectionIndex,
    ArticlePage, SearchPage, LegalPage, CommandPalette,
  } = window;
  const { useTweaks, TweaksPanel, TweakSection, TweakColor, TweakRadio, TweakSlider, TweakToggle } = window;

  // ---- accent presets (brand + readable ink) ----
  const ACCENTS = {
    "#ffe680": "#3a2c00", // soft yolk (logo)
    "#f4c025": "#3a2c00", // egg yolk
    "#e0950f": "#241a00", // amber
    "#d98324": "#ffffff", // honey
    "#3f3f46": "#ffffff", // charcoal
  };
  function inkFor(hex) {
    if (ACCENTS[hex]) return ACCENTS[hex];
    const c = hex.replace("#", "");
    const r = parseInt(c.slice(0, 2), 16), g = parseInt(c.slice(2, 4), 16), b = parseInt(c.slice(4, 6), 16);
    return 0.299 * r + 0.587 * g + 0.114 * b > 150 ? "#3a2c00" : "#ffffff";
  }

  const prefersDark = typeof matchMedia !== "undefined" && matchMedia("(prefers-color-scheme: dark)").matches;

  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "brand": "#f4c025",
    "dark": prefersDark,
    "homeLayout": "editorial",
    "recipeLayout": "sidebar",
    "radius": 0.7,
    "motion": true
  }/*EDITMODE-END*/;

  // ---- routing helpers ----
  function parseHash() {
    const h = (location.hash || "#/").replace(/^#/, "");
    const p = h.split("/").filter(Boolean); // e.g. ["recipes","slug"]
    if (p.length === 0) return { name: "home" };
    if (p[0] === "search") return { name: "search" };
    if (p[0] === "impressum") return { name: "legal", which: "impressum" };
    if (p[0] === "data-protection") return { name: "legal", which: "privacy" };
    if (p[0] === "recipes") return p[1] ? { name: "recipe", slug: p[1] } : { name: "section", section: "recipes" };
    if (p[0] === "ingridients") return p[1] ? { name: "article", section: "ingridients", slug: p[1] } : { name: "section", section: "ingridients" };
    if (p[0] === "techniques") return p[1] ? { name: "article", section: "techniques", slug: p[1] } : { name: "section", section: "techniques" };
    return { name: "home" };
  }
  function toHash(route) {
    switch (route.name) {
      case "home": return "#/";
      case "search": return "#/search";
      case "section": return "#/" + route.section;
      case "recipe": return "#/recipes/" + route.slug;
      case "article": return "#/" + route.section + "/" + route.slug;
      case "legal": return route.which === "impressum" ? "#/impressum" : "#/data-protection";
      default: return "#/";
    }
  }

  function App() {
    const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
    const [route, setRoute] = useState(parseHash());
    const [cmdOpen, setCmdOpen] = useState(false);

    // apply theme + tokens
    useEffect(() => { document.documentElement.classList.toggle("dark", !!t.dark); }, [t.dark]);
    useEffect(() => {
      document.documentElement.style.setProperty("--brand", t.brand);
      document.documentElement.style.setProperty("--brand-fg", inkFor(t.brand));
    }, [t.brand]);
    useEffect(() => { document.documentElement.style.setProperty("--radius", t.radius + "rem"); }, [t.radius]);
    useEffect(() => { document.body.setAttribute("data-motion", t.motion ? "on" : "off"); }, [t.motion]);

    // hash sync
    useEffect(() => {
      const onHash = () => setRoute(parseHash());
      window.addEventListener("hashchange", onHash);
      return () => window.removeEventListener("hashchange", onHash);
    }, []);
    const go = useCallback((r) => {
      const hash = toHash(r);
      if (location.hash !== hash) location.hash = hash; else setRoute(r);
      setRoute(r);
      window.scrollTo(0, 0);
    }, []);

    // ⌘K
    useEffect(() => {
      const onKey = (e) => {
        if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setCmdOpen((v) => !v); }
      };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, []);

    const openCmd = useCallback(() => setCmdOpen(true), []);
    const navGo = useCallback((r) => { setCmdOpen(false); go(r); }, [go]);

    let page;
    if (route.name === "home") page = <Home go={go} openCmd={openCmd} homeLayout={t.homeLayout} />;
    else if (route.name === "section" && route.section === "recipes") page = <RecipesIndex go={go} />;
    else if (route.name === "section") page = <SectionIndex section={route.section} go={go} />;
    else if (route.name === "recipe") page = <RecipeDetail slug={route.slug} go={go} recipeLayout={t.recipeLayout} />;
    else if (route.name === "article") page = <ArticlePage section={route.section} slug={route.slug} go={go} />;
    else if (route.name === "search") page = <SearchPage go={go} />;
    else if (route.name === "legal") page = <LegalPage which={route.which} go={go} />;
    else page = <Home go={go} openCmd={openCmd} homeLayout={t.homeLayout} />;

    const showFooter = route.name !== "search";

    return (
      <>
        <Navbar route={route} go={go} openCmd={openCmd} dark={!!t.dark} onToggleTheme={() => setTweak("dark", !t.dark)} />
        <main key={route.name + (route.slug || route.section || route.which || "")}>{page}</main>
        {showFooter && <Footer go={go} />}

        <CommandPalette open={cmdOpen} onClose={() => setCmdOpen(false)} go={navGo} />

        <TweaksPanel>
          <TweakSection label="Accent — from your logo" />
          <TweakColor label="Accent color" value={t.brand}
            options={Object.keys(ACCENTS)}
            onChange={(v) => setTweak("brand", v)} />
          <TweakToggle label="Dark mode" value={!!t.dark} onChange={(v) => setTweak("dark", v)} />

          <TweakSection label="Home layout" />
          <TweakRadio label="Hero direction" value={t.homeLayout}
            options={["editorial", "plate", "grid"]}
            onChange={(v) => setTweak("homeLayout", v)} />

          <TweakSection label="Recipe layout" />
          <TweakRadio label="Method & ingredients" value={t.recipeLayout}
            options={["sidebar", "linear", "split"]}
            onChange={(v) => setTweak("recipeLayout", v)} />

          <TweakSection label="Feel" />
          <TweakSlider label="Corner radius" value={t.radius} min={0} max={1.3} step={0.05} unit="rem"
            onChange={(v) => setTweak("radius", v)} />
          <TweakToggle label="Animations" value={!!t.motion} onChange={(v) => setTweak("motion", v)} />
        </TweaksPanel>
      </>
    );
  }

  function LoadError({ err }) {
    return (
      <div className="container" style={{ paddingTop: "6rem", textAlign: "center" }}>
        <h1 className="h2">Couldn't load content</h1>
        <p className="muted" style={{ marginTop: ".6rem" }}>{String(err && err.message || err)}</p>
        <p className="muted" style={{ marginTop: ".4rem", fontSize: ".9rem" }}>The markdown files in <code className="mono">/content</code> must be served over http(s).</p>
      </div>
    );
  }

  const root = ReactDOM.createRoot(document.getElementById("root"));
  window.loadContent()
    .then(() => root.render(<App />))
    .catch((err) => { console.error(err); root.render(<LoadError err={err} />); });
})();
