// Top-level App: tab state, file-open routing, layout composition.

const { useState: useStateA, useEffect: useEffectA } = React;

// Read a file path out of the URL hash, e.g. "#/Certifications/OSCP.md".
// Returns the full path only if it maps to a real entry in FILES; otherwise
// null (unknown/empty hash falls back to the Home tab).
function pathFromHash() {
  const h = window.location.hash;
  if (!h || h === "#" || h === "#/") return null;
  const raw = decodeURIComponent(h.replace(/^#\/?/, ""));
  return window.PORTFOLIO_DATA.FILES[raw] ? raw : null;
}

function makeFileTab(path) {
  const meta = window.PORTFOLIO_DATA.FILES[path];
  return {
    id: `file:${path}`,
    kind: "file",
    path,
    label: path.split("/").pop(),
    title: meta?.title,
  };
}

function App() {
  const { FOLDERS } = window.PORTFOLIO_DATA;

  // Tabs: always-present "home" + dynamically opened files. If the page loads
  // with a deep link (#/Folder/file.md), seed that tab so it's open on first
  // paint instead of flashing Home first.
  const initialPath = pathFromHash();
  const [tabs, setTabs] = useStateA(() => {
    const base = [{ id: "home", kind: "home", label: "Home" }];
    if (initialPath) base.push(makeFileTab(initialPath));
    return base;
  });
  const [activeId, setActiveId] = useStateA(
    initialPath ? `file:${initialPath}` : "home"
  );

  // Mobile-only (<860px) view state: which panel fills the screen below the
  // tab bar. On desktop this has no effect — the responsive CSS gates it.
  //   "content" (default) | "tree" | "chat"
  const [mobileView, setMobileView] = useStateA("content");

  const openFile = (path) => {
    if (!window.PORTFOLIO_DATA.FILES[path]) return;
    const id = `file:${path}`;
    setTabs((prev) => {
      if (prev.find((t) => t.id === id)) return prev;
      return [...prev, makeFileTab(path)];
    });
    setActiveId(id);
    setMobileView("content"); // picking a file returns to content on mobile
  };

  // Back/forward and shared links: when the hash changes, open the file it
  // names (or return to Home for an empty/unknown hash).
  useEffectA(() => {
    const onHash = () => {
      const path = pathFromHash();
      if (path) openFile(path);
      else setActiveId("home");
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  // Keep the URL in sync with the active tab so it's always shareable.
  // Files set a hash (which pushes a history entry); switching to Home pushes a
  // clean, hash-less entry so Back returns to the file you were just viewing.
  useEffectA(() => {
    const active = tabs.find((t) => t.id === activeId);
    const path = active?.kind === "file" ? active.path : null;
    if (path) {
      const target = `#/${encodeURI(path)}`;
      if (window.location.hash !== target) window.location.hash = target;
    } else if (window.location.hash) {
      history.pushState(
        null,
        "",
        window.location.pathname + window.location.search
      );
    }
  }, [activeId, tabs]);

  // Selecting any tab (incl. Home) returns to content on mobile.
  const selectTab = (id) => {
    setActiveId(id);
    setMobileView("content");
  };

  // Tab-bar buttons toggle their panel; pressing again returns to content.
  const toggleTree = () =>
    setMobileView((v) => (v === "tree" ? "content" : "tree"));
  const toggleChat = () =>
    setMobileView((v) => (v === "chat" ? "content" : "chat"));

  const closeTab = (id) => {
    setTabs((prev) => {
      const idx = prev.findIndex((t) => t.id === id);
      if (idx < 0) return prev;
      const next = prev.filter((t) => t.id !== id);
      if (activeId === id) {
        const fallback = next[idx - 1] || next[idx] || next[0];
        setActiveId(fallback.id);
      }
      return next;
    });
  };

  const activeTab = tabs.find((t) => t.id === activeId) || tabs[0];
  const openPath = activeTab?.kind === "file" ? activeTab.path : null;
  const openMeta = openPath ? window.PORTFOLIO_DATA.FILES[openPath] : null;
  const contentClass =
    activeTab.kind === "home"
      ? "content is-home"
      : openMeta?.kind === "binary"
      ? "content is-binary"
      : "content";

  return (
    <div className={`app mobile-view-${mobileView}`}>
      <window.ChatSidebar />

      <main className="main">
        <window.TabBar
          tabs={tabs}
          activeId={activeId}
          onSelect={selectTab}
          onClose={closeTab}
          mobileView={mobileView}
          onToggleTree={toggleTree}
          onToggleChat={toggleChat}
        />

        <div className="main-body">
          <window.FileTree
            folders={FOLDERS}
            openPath={openPath}
            onOpenFile={openFile}
          />

          <section className={contentClass} key={activeTab.id}>
            {activeTab.kind === "home"
              ? <window.HomeView onOpenFile={openFile} />
              : <window.FileView path={activeTab.path} />}
          </section>
        </div>
      </main>
    </div>
  );
}

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