// app.jsx — root: hash router, app shell (banner + nav + main), content loading,
// theme, command palette. Mounts the application.

const { useState, useEffect, useCallback, useMemo } = React;

function parseHash() {
  let h = location.hash.replace(/^#\/?/, "");
  const [path] = h.split("?");
  const parts = path.split("/").filter(Boolean).map(decodeURIComponent);
  if (parts.length === 0) return { view: "home" };
  if (parts[0] === "map") return { view: "map" };
  if (parts[0] === "search") return { view: "home", search: true };
  if (parts[0] === "specs" || parts[0] === "runbooks") {
    return parts[1] ? { view: "doc", collection: parts[0], id: parts.slice(1).join("/") } : { view: "gallery", collection: parts[0] };
  }
  return { view: "home" };
}

function useTheme() {
  const [theme, setTheme] = useState(() => localStorage.getItem("ukdocs.theme") || "light");
  useEffect(() => {
    document.documentElement.setAttribute("data-uk-theme", theme);
    document.documentElement.style.colorScheme = theme;
    localStorage.setItem("ukdocs.theme", theme);
  }, [theme]);
  return [theme, () => setTheme((t) => (t === "dark" ? "light" : "dark"))];
}

function App() {
  const [route, setRoute] = useState(parseHash);
  const [index, setIndex] = useState(null);
  const [loadState, setLoadState] = useState("loading");
  const [paletteOpen, setPaletteOpen] = useState(false);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [galleryQuery, setGalleryQuery] = useState("");
  const [theme, toggleTheme] = useTheme();

  // routing
  useEffect(() => {
    const on = () => { setRoute(parseHash()); setDrawerOpen(false); setPaletteOpen(false); };
    window.addEventListener("hashchange", on);
    return () => window.removeEventListener("hashchange", on);
  }, []);
  useEffect(() => { if (route.search) setPaletteOpen(true); }, [route.search]);

  const navigate = useCallback((href) => { if (location.hash === href) setRoute(parseHash()); else location.hash = href; }, []);
  const openDoc = useCallback((doc) => {
    if (!doc) return;
    let coll = doc.collection;
    if (!coll && index) { const found = (index.documents || []).find((d) => d.id === doc.id); coll = found && found.collection; }
    if (!coll) return;
    navigate("#/" + coll + "/" + encodeURIComponent(doc.id));
  }, [index, navigate]);

  // content load
  const load = useCallback(() => {
    setLoadState("loading");
    fetch("content/index.json")
      .then((r) => { if (!r.ok) throw new Error("HTTP " + r.status); return r.json(); })
      .then((d) => { setIndex(d); setLoadState("ready"); })
      .catch(() => setLoadState("error"));
  }, []);
  useEffect(() => { load(); }, [load]);

  // global ⌘K
  useEffect(() => {
    const on = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setPaletteOpen((o) => !o); }
    };
    document.addEventListener("keydown", on);
    return () => document.removeEventListener("keydown", on);
  }, []);

  const activeNav = route.view === "home" ? "home" : route.view === "map" ? "map" : route.collection || "home";
  const collections = index ? index.collections : [];

  const crumbs = useMemo(() => {
    const c = [{ label: "Library", href: "#/" }];
    if (!index) return c;
    if (route.view === "map") c.push({ label: "Map" });
    else if (route.view === "gallery") c.push({ label: collLabel(index, route.collection) });
    else if (route.view === "doc") {
      c.push({ label: collLabel(index, route.collection), href: "#/" + route.collection });
      const d = (index.documents || []).find((x) => x.id === route.id);
      c.push({ label: d ? shortText(d.title, 40) : route.id });
    }
    return c;
  }, [route, index]);

  let body;
  if (loadState === "loading") body = <Loading label="Loading the library…" />;
  else if (loadState === "error") body = <div className="page"><ErrorState title="Couldn’t load the library" msg="content/index.json is missing. Run `npm run build:content` to generate it from docs/specs and docs/runbooks, then reload." onRetry={load} /></div>;
  else if (route.view === "home") body = <Overview index={index} onNavigate={navigate} onOpenDoc={openDoc} />;
  else if (route.view === "map") body = <MapPage index={index} onOpenDoc={openDoc} />;
  else if (route.view === "gallery") body = <Gallery key={route.collection} collectionId={route.collection} index={index} onOpenDoc={openDoc} query={galleryQuery} onQuery={setGalleryQuery} />;
  else if (route.view === "doc") body = <Viewer key={route.id} docId={route.id} index={index} onOpenDoc={openDoc} onNavigate={navigate} />;

  return (
    <div className="app">
      <Banner crumbs={crumbs} onMenu={() => setDrawerOpen(true)} onSearch={() => setPaletteOpen(true)}
              theme={theme} onToggleTheme={toggleTheme} onHome={() => navigate("#/")} />
      <div className="app__body">
        <Nav active={activeNav} collections={collections} onNavigate={navigate} />
        <main className="app__main">{body}</main>
      </div>
      <Drawer open={drawerOpen} onClose={() => setDrawerOpen(false)} active={activeNav} collections={collections} onNavigate={navigate} />
      {index && <CommandPalette index={index} open={paletteOpen} onClose={() => setPaletteOpen(false)} onOpenDoc={openDoc} />}
    </div>
  );
}

function collLabel(index, id) { const c = (index.collections || []).find((x) => x.id === id); return c ? c.label : id; }

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