// tomugi-app.jsx — app orchestration and routing (home <-> series)

function App() {
  const { useEffect, useRef, useState } = React;
  const [t, setTweak] = useTweaks(window.TomugiConfig.tweaks);
  const { user, signIn, signOut } = useTomugiAuth();

  // Restore the last view on reload (per-tab, via sessionStorage) so a refresh
  // keeps you where you were instead of bouncing back to home.
  const NAV_KEY = "tomugi:nav";
  const savedNav = (() => {
    try { return JSON.parse(sessionStorage.getItem(NAV_KEY) || "null"); } catch (e) { return null; }
  })();
  const seriesById = (id) => (window.TOMUGI_SERIES || []).find((s) => String(s.id) === String(id)) || null;
  const restoredCurrent = savedNav && savedNav.view === "series" ? seriesById(savedNav.currentId) : null;
  const restoredView = !savedNav ? "home"
    : (savedNav.view === "series" && !restoredCurrent ? "home" : (savedNav.view || "home"));
  const savedCatalog = (savedNav && savedNav.catalog) || {};

  const [view, setView] = useState(restoredView); // home | catalog | series
  const [previousView, setPreviousView] = useState((savedNav && savedNav.previousView) || "home");
  const [current, setCurrent] = useState(restoredCurrent);
  const [authMode, setAuthMode] = useState(null);
  const [catalogState, setCatalogState] = useState({ filter: savedCatalog.filter || "All", page: savedCatalog.page || 1, scrollY: 0 });
  const [highlightedSeriesId, setHighlightedSeriesId] = useState(null);
  const [showTop, setShowTop] = useState(false);
  const restoreCatalogScroll = useRef(null);
  const catalogScrollY = useRef(0);

  useEffect(() => { document.documentElement.style.setProperty("--accent", t.accent); }, [t.accent]);
  useEffect(() => { document.documentElement.setAttribute("data-tone", t.tone); }, [t.tone]);
  useEffect(() => {
    const el = document.getElementById("app-loader");
    if (!el) return;
    el.classList.add("is-hidden");
    const timer = setTimeout(() => el.remove(), 500);
    return () => clearTimeout(timer);
  }, []);
  useEffect(() => {
    const onScroll = () => setShowTop(window.scrollY > 480);
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  useEffect(() => {
    if (view !== "catalog" || restoreCatalogScroll.current == null) return;
    const target = restoreCatalogScroll.current;
    restoreCatalogScroll.current = null;
    requestAnimationFrame(() => {
      requestAnimationFrame(() => window.scrollTo({ top: target, behavior: "auto" }));
    });
  }, [view, catalogState.filter, catalogState.page]);
  useEffect(() => {
    if (!highlightedSeriesId) return;
    const timer = setTimeout(() => setHighlightedSeriesId(null), 3200);
    return () => clearTimeout(timer);
  }, [highlightedSeriesId]);
  useEffect(() => {
    try {
      sessionStorage.setItem(NAV_KEY, JSON.stringify({
        view,
        previousView,
        currentId: current ? current.id : null,
        catalog: { filter: catalogState.filter, page: catalogState.page },
      }));
    } catch (e) { /* storage unavailable — non-fatal */ }
  }, [view, previousView, current, catalogState.filter, catalogState.page]);

  function openSeries(s) {
    setHighlightedSeriesId(null);
    if (view === "catalog") {
      catalogScrollY.current = window.scrollY;
      setCatalogState((prev) => ({ ...prev, scrollY: catalogScrollY.current }));
    }
    setCurrent(s);
    setPreviousView(view === "series" ? previousView : view);
    setView("series");
    window.scrollTo({ top: 0 });
  }
  function openCatalog(opts) {
    // Fresh entry → page 1, top of the list. If a genre is passed (from a
    // genre tag), filter the catalog by it and reset the status filter.
    const genre = opts && opts.genre ? opts.genre : null;
    restoreCatalogScroll.current = null;
    catalogScrollY.current = 0;
    setCatalogState((prev) => ({ ...prev, page: 1, scrollY: 0, genre, filter: genre ? "All" : prev.filter }));
    setView("catalog");
    window.scrollTo({ top: 0 });
  }
  function goHome() { setView("home"); window.scrollTo({ top: 0 }); }
  function goBackFromSeries() {
    // "Back to catalog" always lands on the full catalog page. If we came from
    // there, restore scroll; otherwise (e.g. opened from the home preview) open
    // the catalog fresh at the top. Either way, highlight the series we left.
    setHighlightedSeriesId(current?.id || null);
    if (previousView === "catalog") {
      restoreCatalogScroll.current = catalogScrollY.current;
    } else {
      window.scrollTo({ top: 0 });
    }
    setView("catalog");
  }

  function onNav(id) {
    if (view !== "home") { setView("home"); setTimeout(() => scrollToId(id), 60); }
    else scrollToId(id);
  }

  return (
    <div className={`app app-view-${view} ${showTop ? "is-scrolled" : ""}`}>
      <Nav onNav={onNav} view={view} user={user} onAuth={setAuthMode} onSignOut={signOut} />

      {view === "home" ? (
        <React.Fragment>
          <Hero onNav={onNav} showTexture={t.texture} onBrowse={openCatalog} onOpen={openSeries} />
          <section className="section feature" id="organize">
            <div className="section-head">
              <div>
                <div className="eyebrow mono">How it works</div>
                <h2 className="section-h2">From loose chapters to<br />clean volumes.</h2>
                <p className="section-lead">
                  You've got the chapters; tomugi knows which volume each one belongs to.
                  Point it at your folder and the whole series is organized in one click.
                </p>
              </div>
            </div>
            <Steps />
          </section>
          <CatalogPreview showTexture={t.texture} onOpen={openSeries} onBrowse={openCatalog} />
          <Tiers />
        </React.Fragment>
      ) : view === "catalog" ? (
        <CatalogPage
          showTexture={t.texture}
          onOpen={openSeries}
          onBack={goHome}
          catalogState={catalogState}
          onCatalogState={setCatalogState}
          highlightedSeriesId={highlightedSeriesId}
        />
      ) : (
        <SeriesPage key={current && current.id} series={current} onBack={goBackFromSeries} onOpen={openSeries} onGenre={(g) => openCatalog({ genre: g })} showTexture={t.texture} />
      )}

      <Footer />

      <TweaksPanel>
        <TweakSection label="Accent color" />
        <TweakColor label="Accent" value={t.accent}
          options={["#EC5B46", "#7C7BF0", "#43C49B", "#E6A94B"]}
          onChange={(v) => setTweak("accent", v)} />
        <TweakSection label="Ambience" />
        <TweakRadio label="Background tone" value={t.tone}
          options={["cool", "warm", "neutral"]}
          onChange={(v) => setTweak("tone", v)} />
        <TweakToggle label="Cover texture" value={t.texture}
          onChange={(v) => setTweak("texture", v)} />
      </TweaksPanel>

      <AuthModal
        mode={authMode || "signin"}
        open={!!authMode}
        onClose={() => setAuthMode(null)}
        onSubmit={signIn}
      />
      <button
        className="scroll-top-fab"
        aria-label="Scroll to top"
        onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
      >
        <span aria-hidden="true">↑</span>
      </button>
    </div>
  );
}

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