// App root: handles routing, language state, search state
// v2: awaits window.__DAYS_READY (set by days.js) before first render

function App() {
  const [ready, setReady] = React.useState(!!window.DAYS);
  const [view, setView]   = React.useState(() => parseHash().view);
  const [openIso, setOpenIso] = React.useState(() => parseHash().iso);
  const [lang, setLang]   = React.useState(() => localStorage.getItem("adm:lang") || "cht");
  const [query, setQuery] = React.useState("");

  // Wait for days to load from API
  React.useEffect(() => {
    if (window.DAYS) { setReady(true); return; }
    (window.__DAYS_READY || Promise.resolve()).then(() => setReady(true));
  }, []);

  function parseHash() {
    const h = window.location.hash.replace(/^#/, "");
    if (h.startsWith("entry/")) return { view: "entry", iso: h.slice("entry/".length) };
    if (h === "about") return { view: "about", iso: null };
    if (h === "admin") return { view: "admin", iso: null };
    return { view: "archive", iso: null };
  }

  // Sync body class for language fonts
  React.useEffect(() => {
    document.body.classList.toggle("lang-eng", lang === "eng");
    localStorage.setItem("adm:lang", lang);
    document.documentElement.lang = lang === "cht" ? "zh-Hant" : "en";
  }, [lang]);

  // Hash sync
  React.useEffect(() => {
    let h = "";
    if (view === "entry" && openIso) h = "entry/" + openIso;
    else if (view === "about") h = "about";
    else if (view === "admin") h = "admin";
    if (("#" + h) !== window.location.hash) window.location.hash = h;
  }, [view, openIso]);

  React.useEffect(() => {
    const onHash = () => {
      const p = parseHash();
      setView(p.view);
      setOpenIso(p.iso);
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  // Nav helpers
  function navTo(v) {
    if (v === "archive") { setView("archive"); setOpenIso(null); }
    else if (v === "about") setView("about");
    else if (v === "admin") setView("admin");
    window.scrollTo({ top: 0, behavior: "instant" });
  }
  function openEntry(iso) {
    setView("entry");
    setOpenIso(iso);
  }

  // Loading screen while /api/list is in-flight
  if (!ready) {
    return (
      <div style={{
        minHeight: "100vh",
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
        justifyContent: "center",
        gap: 16,
        color: "var(--ink-muted)",
        fontFamily: "var(--font-body)",
      }}>
        <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
          <circle cx="20" cy="20" r="16" stroke="var(--gold)" strokeWidth="2" strokeLinecap="round"
            strokeDasharray="60 40" style={{ transformOrigin: "center", animation: "spin 1.2s linear infinite" }} />
        </svg>
        <div style={{ fontSize: 14, letterSpacing: "0.06em" }}>
          {lang === "cht" ? "載入每日靜思中…" : "Loading daily moments…"}
        </div>
        <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
      </div>
    );
  }

  return (
    <>
      <TopBar lang={lang} setLang={setLang} query={query} setQuery={setQuery} onNav={navTo} view={view} />
      {view === "archive" && <ArchiveView lang={lang} query={query} onOpen={openEntry} />}
      {view === "entry"   && <EntryView   lang={lang} iso={openIso} onNav={navTo} onOpen={openEntry} />}
      {view === "about"   && <AboutView    lang={lang} />}
      {view === "admin"   && <AdminView    lang={lang} />}
      <BBFoot lang={lang} />
    </>
  );
}

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