// Router
function parseHash() {
  const h = (location.hash || "#/").replace(/^#/, "");
  const parts = h.split("/").filter(Boolean);
  if (parts.length === 0) return { page: "home" };
  if (parts[0] === "chapter" && parts[1]) return { page: "chapter", slug: parts[1] };
  if (parts[0] === "about") return { page: "about" };
  if (parts[0] === "hire") return { page: "hire" };
  return { page: "home" };
}

function useRoute() {
  const [route, setRoute] = React.useState(parseHash());
  React.useEffect(() => {
    const onHash = () => {
      setRoute(parseHash());
      window.scrollTo({ top: 0, behavior: "instant" });
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  const go = (page, slug) => {
    if (page === "chapter" && slug) location.hash = "#/chapter/" + slug;
    else if (page === "home") location.hash = "#/";
    else location.hash = "#/" + page;
  };
  return [route, go];
}

// Tweak defaults block — editable via host protocol
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#34d399",
  "bgBase": "#0a0a0a",
  "contentMax": 760,
  "theme": "dark",
  "proseFont": "Geist",
  "monoFont": "Geist Mono",
  "showLiveTerminal": true
}/*EDITMODE-END*/;

const ACCENT_OPTIONS = [
  { label: "Emerald", value: "#34d399" },
  { label: "Amber",   value: "#f59e0b" },
  { label: "Orange",  value: "#ff6b3d" },
  { label: "Indigo",  value: "#8b9cff" },
  { label: "Rose",    value: "#f472b6" },
];
const BG_OPTIONS = [
  { label: "Pitch (#0a0a0a)",  value: "#0a0a0a" },
  { label: "Forest (#0f1311)", value: "#0f1311" },
  { label: "Ink (#13151a)",    value: "#13151a" },
  { label: "Warm (#1a1814)",   value: "#1a1814" },
];
const PROSE_FONT_OPTIONS = [
  { label: "Geist",       value: "Geist" },
  { label: "Inter Tight", value: "Inter Tight" },
  { label: "IBM Plex Sans", value: "IBM Plex Sans" },
  { label: "Newsreader",  value: "Newsreader" },
];
const MONO_FONT_OPTIONS = [
  { label: "Geist Mono",    value: "Geist Mono" },
  { label: "JetBrains Mono",value: "JetBrains Mono" },
  { label: "IBM Plex Mono", value: "IBM Plex Mono" },
];

function applyTweaks(t) {
  const root = document.documentElement;
  root.setAttribute("data-theme", t.theme || "dark");
  // Only override palette-derived values in dark mode — in light mode, the
  // CSS [data-theme="light"] block owns the palette.
  if (t.theme === "dark") {
    root.style.setProperty("--accent", t.accent);
    root.style.setProperty("--accent-ghost", hexWithAlpha(t.accent, 0.10));
    root.style.setProperty("--accent-dim", mixWithBlack(t.accent, 0.55));
    root.style.setProperty("--bg", t.bgBase);
    root.style.setProperty("--bg-1", lighten(t.bgBase, 0.02));
    root.style.setProperty("--bg-2", lighten(t.bgBase, 0.04));
    root.style.setProperty("--bg-3", lighten(t.bgBase, 0.06));
  } else {
    // Clear inline overrides so the light palette from CSS applies cleanly.
    ["--accent","--accent-ghost","--accent-dim","--bg","--bg-1","--bg-2","--bg-3"].forEach(k => root.style.removeProperty(k));
  }
  root.style.setProperty("--content-max", (t.contentMax || 760) + "px");
  root.style.setProperty("--ff-sans", `"${t.proseFont}", ui-sans-serif, system-ui, sans-serif`);
  root.style.setProperty("--ff-mono", `"${t.monoFont}", ui-monospace, SFMono-Regular, Menlo, monospace`);
}

// color helpers (very small — enough for our palette)
function hexToRgb(hex) {
  const h = hex.replace("#", "");
  const n = parseInt(h.length === 3 ? h.split("").map(c => c+c).join("") : h, 16);
  return { r: (n>>16)&255, g: (n>>8)&255, b: n&255 };
}
function rgbToHex({r,g,b}) {
  return "#" + [r,g,b].map(v => Math.max(0,Math.min(255,Math.round(v))).toString(16).padStart(2,"0")).join("");
}
function hexWithAlpha(hex, a) {
  const {r,g,b} = hexToRgb(hex);
  return `rgba(${r}, ${g}, ${b}, ${a})`;
}
function mixWithBlack(hex, amt) { // 0 = original, 1 = black
  const c = hexToRgb(hex);
  return rgbToHex({ r: c.r*(1-amt), g: c.g*(1-amt), b: c.b*(1-amt) });
}
function lighten(hex, amt) { // add amt*255 per channel
  const c = hexToRgb(hex);
  return rgbToHex({ r: c.r + 255*amt, g: c.g + 255*amt, b: c.b + 255*amt });
}

// Load optional fonts on demand
function ensureFont(family) {
  const key = "font-" + family.replace(/\s+/g, "-");
  if (document.getElementById(key)) return;
  const map = {
    "Inter Tight":   "https://fonts.googleapis.com/css2?family=Inter+Tight:wght@300;400;500;600;700&display=swap",
    "IBM Plex Sans": "https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600;700&display=swap",
    "IBM Plex Mono": "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap",
    "Newsreader":    "https://fonts.googleapis.com/css2?family=Newsreader:wght@400;500;600;700&display=swap",
    "JetBrains Mono":"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap",
  };
  if (!map[family]) return;
  const link = document.createElement("link");
  link.id = key;
  link.rel = "stylesheet";
  link.href = map[family];
  document.head.appendChild(link);
}

function App() {
  const [route, go] = useRoute();
  const [tweaks, setTweaks] = useTweaks(TWEAK_DEFAULTS);

  React.useEffect(() => {
    ensureFont(tweaks.proseFont);
    ensureFont(tweaks.monoFont);
    applyTweaks(tweaks);
  }, [tweaks]);

  return (
    <div className="app">
      <Sidebar route={route} go={go} />
      <main className="main">
        <TopBar route={route} go={go} theme={tweaks.theme} toggleTheme={() => setTweaks({ theme: tweaks.theme === "dark" ? "light" : "dark" })} />
        <MobileNav route={route} go={go} />
        {route.page === "home"    && <HomePage go={go} />}
        {route.page === "chapter" && <ChapterPage slug={route.slug} go={go} />}
        {route.page === "about"   && <AboutPage go={go} />}
        {route.page === "hire"    && <HirePage go={go} />}
      </main>

      <TweaksPanel title="Tweaks">
        <TweakSection title="Theme">
          <TweakRadio label="Mode" value={tweaks.theme}
            options={[{label:"Dark",value:"dark"},{label:"Light",value:"light"}]}
            onChange={(v) => setTweaks({ theme: v })} />
          <TweakSelect label="Accent" value={tweaks.accent}
            options={ACCENT_OPTIONS}
            onChange={(v) => setTweaks({ accent: v })} />
          <TweakSelect label="Background tone" value={tweaks.bgBase}
            options={BG_OPTIONS}
            onChange={(v) => setTweaks({ bgBase: v })} />
        </TweakSection>

        <TweakSection title="Typography">
          <TweakSelect label="Prose font" value={tweaks.proseFont}
            options={PROSE_FONT_OPTIONS}
            onChange={(v) => setTweaks({ proseFont: v })} />
          <TweakSelect label="Mono font" value={tweaks.monoFont}
            options={MONO_FONT_OPTIONS}
            onChange={(v) => setTweaks({ monoFont: v })} />
        </TweakSection>

        <TweakSection title="Layout">
          <TweakSlider label="Content max (px)" value={tweaks.contentMax}
            min={640} max={920} step={10}
            onChange={(v) => setTweaks({ contentMax: v })} />
          <TweakToggle label="Live terminal on home"
            value={tweaks.showLiveTerminal}
            onChange={(v) => setTweaks({ showLiveTerminal: v })} />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

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