// Root app + router. Single-source-of-truth state for which page is showing.
const { useState: useStateApp, useEffect: useEffectApp } = React;

// Self-healing bootstrap. tomhogan.io sits behind a Cloudflare cache that can hold an older
// index.html for hours. If that stale index did not load the newer modules, fetch, transform,
// and evaluate them here before rendering, so every visitor gets the current site.
async function ensureModules() {
  const needed = ["app/track_data.jsx", "app/resume.jsx", "app/real_pages.jsx"].filter(
    (src) => !document.querySelector('script[src="' + src + '"]')
  );
  for (const src of needed) {
    try {
      const code = await (await fetch(src, { cache: "no-store" })).text();
      const out = window.Babel.transform(code, { presets: ["react"], filename: src }).code;
      (0, eval)(out);
    } catch (err) { console.warn("module load failed", src, err); }
  }
}

function App() {
  const VALID = ["home", "essay", "archive", "about", "subscribe", "manifesto", "loop", "projects", "notes", "elsewhere", "disclosure", "track", "partners"];
  function parseHash() {
    const h = (window.location.hash || "").replace(/^#/, "");
    const [name, ...rest] = h.split("/");
    const param = rest.length ? decodeURIComponent(rest.join("/")) : "";
    if (!VALID.includes(name)) return { name: "home", params: {} };
    if (name === "essay" && param) return { name, params: { id: param } };
    if (name === "archive" && param) return { name, params: { tag: param } };
    if (name === "projects" && param) return { name, params: { id: param } };
    return { name, params: {} };
  }
  const initialRoute = parseHash();
  const [route, setRoute] = useStateApp(initialRoute);
  const [searchOpen, setSearchOpen] = useStateApp(false);

  function navigate(name, params = {}) {
    setRoute({ name, params });
    const h = "#" + name + (params.id ? "/" + encodeURIComponent(params.id) : params.tag ? "/" + encodeURIComponent(params.tag) : "");
    if (window.location.hash !== h) window.history.pushState(null, "", h);
    window.scrollTo({ top: 0, behavior: "instant" });
  }

  // Back and forward buttons, and links that set the hash directly
  useEffectApp(() => {
    function onPop() { setRoute(parseHash()); }
    window.addEventListener("popstate", onPop);
    window.addEventListener("hashchange", onPop);
    return () => { window.removeEventListener("popstate", onPop); window.removeEventListener("hashchange", onPop); };
  }, []);

  // ⌘K / Ctrl-K opens search
  useEffectApp(() => {
    function onKey(e) {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setSearchOpen((s) => !s);
      }
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  let page;
  switch (route.name) {
    case "home":      page = <HomePage navigate={navigate} />; break;
    case "essay":     page = <EssayReader id={route.params.id} navigate={navigate} />; break;
    case "archive":   page = <ArchivePage navigate={navigate} initialTag={route.params.tag} />; break;
    case "about":     page = <AboutPage navigate={navigate} />; break;
    case "subscribe": page = <SubscribePage navigate={navigate} />; break;
    case "manifesto": page = <ManifestoPage navigate={navigate} />; break;
    case "loop":      page = <LoopPage navigate={navigate} />; break;
    case "projects":  page = <ProjectsPage navigate={navigate} initialId={route.params.id} />; break;
    case "notes":     page = <NotesPage navigate={navigate} />; break;
    case "elsewhere": page = <ElsewherePage navigate={navigate} />; break;
    case "disclosure": page = <DisclosurePage navigate={navigate} />; break;
    case "track":      page = <TrackRecordPage navigate={navigate} />; break;
    case "partners":   page = <PartnersPage navigate={navigate} />; break;
    default:          page = <HomePage navigate={navigate} />;
  }

  return (
    <div className="th-app">
      <TopBar
        route={route.name}
        navigate={navigate}
        onOpenSearch={() => setSearchOpen(true)}
      />
      <main className="th-main">{page}</main>
      <PageFooter navigate={navigate} />
      <SearchOverlay
        open={searchOpen}
        onClose={() => setSearchOpen(false)}
        navigate={navigate}
      />
    </div>
  );
}

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