// Main app shell: sidebar + router

const { useEffect, useState, useRef } = React;

/* ---------- Live clock ---------- */
function useClock() {
  const [t, setT] = useState(() => new Date());
  useEffect(() => {
    const id = setInterval(() => setT(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  const pad = (n) => String(n).padStart(2, "0");
  return `${pad(t.getHours())}:${pad(t.getMinutes())}:${pad(t.getSeconds())}`;
}

/* ---------- Hash router ---------- */
function useRoute() {
  const [hash, setHash] = useState(() => location.hash || "#/");
  useEffect(() => {
    const onChange = () => setHash(location.hash || "#/");
    window.addEventListener("hashchange", onChange);
    return () => window.removeEventListener("hashchange", onChange);
  }, []);
  // parse
  const clean = hash.replace(/^#\/?/, "");
  const parts = clean.split("/").filter(Boolean);
  if (parts.length === 0) return { name: "home" };
  if (parts[0] === "about") return { name: "about" };
  if (parts[0] === "musings") return { name: "musings" };
  if (parts[0] === "projects") return { name: "projects" };
  if (parts[0] === "contact") return { name: "contact" };
  if (parts[0] === "essay") return { name: "essay", slug: parts[1] };
  return { name: "home" };
}

/* ---------- Sidebar ---------- */
function Sidebar({ route, layout }) {
  const items = [
    { href: "#/", label: "Home", match: (r) => r.name === "home" },
    { href: "#/about", label: "About", match: (r) => r.name === "about" },
    { href: "#/musings", label: "Musings", match: (r) => r.name === "musings" || r.name === "essay" },
    { href: "#/projects", label: "Projects", match: (r) => r.name === "projects" },
    { href: "#/contact", label: "Contact", match: (r) => r.name === "contact" },
  ];
  return (
    <aside className="sidebar">
      <div className="brand"></div>
      <nav className="nav">
        {items.map((it) => (
          <a
            key={it.href}
            href={it.href}
            className={it.match(route) ? "active" : ""}
            onClick={(e) => { e.preventDefault(); location.hash = it.href; }}
          >
            {it.label}
          </a>
        ))}
      </nav>
      <div className="meta">
        © {new Date().getFullYear()}<br/>
        sf · everywhere
      </div>
    </aside>
  );
}

/* ---------- Top-center nav (always visible on home) ---------- */
function FloatingNav({ route, visible = true, compact = false }) {
  const items = [
    { href: "#/", label: "Home", match: (r) => r.name === "home" },
    { href: "#/about", label: "About", match: (r) => r.name === "about" },
    { href: "#/musings", label: "Musings", match: (r) => r.name === "musings" || r.name === "essay" },
    { href: "#/projects", label: "Projects", match: (r) => r.name === "projects" },
    { href: "#/contact", label: "Contact", match: (r) => r.name === "contact" },
  ];
  return (
    <div
      className={`nav-shell ${visible ? "on" : ""} ${compact ? "compact" : "expanded"}`}
      tabIndex={compact ? 0 : -1}
      aria-label={compact ? "Open navigation" : undefined}
    >
      {compact && <span className="nav-dot" aria-hidden="true" />}
      <nav className="float-nav" aria-label="Primary">
        {items.map((it) => (
          <a
            key={it.href}
            href={it.href}
            className={it.match(route) ? "active" : ""}
            onClick={(e) => { e.preventDefault(); location.hash = it.href; }}
          >
            {it.label}
          </a>
        ))}
      </nav>
    </div>
  );
}

/* ---------- App ---------- */
function App() {
  const route = useRoute();
  const [tweaks, setTweak] = useTweaks(window.__TWEAK_DEFAULTS__);
  const [introKey, setIntroKey] = useState(0);

  // Replay intro on first home visit + manual replay
  const lastRoute = useRef(route.name);
  useEffect(() => {
    if (route.name === "home" && lastRoute.current !== "home") {
      setIntroKey((k) => k + 1);
    }
    lastRoute.current = route.name;
  }, [route.name]);

  // Lenis smooth scroll
  useEffect(() => {
    if (!window.Lenis) return;
    const lenis = new window.Lenis({
      duration: 1.2,
      easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
      smoothWheel: true,
    });
    function raf(time) { lenis.raf(time); requestAnimationFrame(raf); }
    requestAnimationFrame(raf);
    return () => lenis.destroy();
  }, []);

  // Track scroll position
  const [scrollY, setScrollY] = useState(0);
  useEffect(() => {
    const onScroll = () => setScrollY(window.scrollY);
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  // Scroll to top on route change (within page transitions)
  useEffect(() => {
    window.scrollTo({ top: 0, behavior: "auto" });
  }, [route.name, route.slug]);

  let pageEl = null;
  if (route.name === "home")     pageEl = <HomePage introKey={introKey} />;
  else if (route.name === "about")    pageEl = <AboutPage />;
  else if (route.name === "musings")  pageEl = <MusingsPage />;
  else if (route.name === "projects") pageEl = <ProjectsPage />;
  else if (route.name === "contact")  pageEl = <ContactPage />;
  else if (route.name === "essay")    pageEl = <EssayPage slug={route.slug} />;

  const isHome = route.name === "home";
  // Hide nav once user scrolls. Home: more leeway (hero is full viewport).
  // Subpages: fade as soon as scroll starts.
  const navVisible = isHome ? scrollY < 120 : scrollY < 24;

  return (
    <>
      <div className="app home-app">
        <main key={route.name + (route.slug || "")}>
          {pageEl}
        </main>
        <FloatingNav route={route} visible={navVisible} compact={!isHome} />
      </div>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Intro" />
        <TweakButton label="Replay typewriter" onClick={() => { location.hash = "#/"; setIntroKey((k) => k + 1); }} />
      </TweaksPanel>
    </>
  );
}

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