// ─────────────────────────────────────────────────────────────────────────
// Meridian — root app: real auth gate, theme, router, app shell, Hermes panel
// ─────────────────────────────────────────────────────────────────────────
const { useState: useS, useEffect: useE, useRef: useR, useCallback: useCb } = React;

function useTheme() {
  const [theme, setTheme] = useS(() => localStorage.getItem("meridian-theme") || "light");
  useE(() => {
    document.documentElement.setAttribute("data-theme", theme);
    localStorage.setItem("meridian-theme", theme);
  }, [theme]);
  return [theme, () => setTheme((t) => (t === "dark" ? "light" : "dark"))];
}

/* ── Shared portfolio store ───────────────────────────────────────────────── */
// Loads positions + balance + recommendations once; maps to design shapes.
function usePortfolioStore(enabled) {
  const [state, setState] = useS({ loading: true, error: null, data: null });

  const load = useCb(async () => {
    if (!enabled) return;
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const [posRes, balRes, recRes] = await Promise.all([
        API.positions(),
        API.balance(),
        API.recommendations().catch(() => ({ recommendations: [] })),
      ]);
      const recs = (recRes && recRes.recommendations) || [];
      const recBySym = {};
      recs.forEach((r) => {
        if (r.sym) recBySym[r.sym.toUpperCase()] = r;
        if (r.isin) recBySym[r.isin.toUpperCase()] = r;
      });
      const rawPos = (posRes && posRes.positions) || [];
      const positions = rawPos.map((p) => API.map.mapPosition(p, recBySym));
      const summary = API.map.summaryFromBalance(balRes || {}, positions.length, posRes && posRes.as_of);
      const sectors = API.map.sectorsFromPositions(positions, summary.totalValue);
      const concentration = API.map.concentrationFrom(positions, sectors, summary.totalValue);
      setState({ loading: false, error: null, data: { positions, summary, sectors, concentration, recs, recBySym, asOf: (posRes && posRes.as_of) || (balRes && balRes.as_of), source: balRes && balRes.source } });
    } catch (error) {
      setState({ loading: false, error, data: null });
    }
  }, [enabled]);

  useE(() => { if (enabled) load(); }, [enabled, load]);
  return { ...state, reload: load };
}

function App() {
  const [auth, setAuth] = useS("checking"); // checking | out | in
  const [user, setUser] = useS(null);
  const [theme, toggleTheme] = useTheme();
  const [screen, setScreen] = useS("today");
  const [stock, setStock] = useS(null);
  const [panelOpen, setPanelOpen] = useS(false);
  const [refreshing, setRefreshing] = useS(false);
  const mainRef = useR(null);

  // initial auth check
  useE(() => {
    let live = true;
    API.me().then(
      (r) => { if (!live) return; if (r && r.user) { setUser(r.user); setAuth("in"); if (r.user.must_rotate) setScreen("settings"); } else setAuth("out"); },
      () => { if (live) setAuth("out"); }
    );
    return () => { live = false; };
  }, []);

  // global 401 handler — session expired mid-use
  useE(() => {
    const onUnauth = () => { setAuth("out"); setUser(null); };
    window.addEventListener("meridian-unauth", onUnauth);
    return () => window.removeEventListener("meridian-unauth", onUnauth);
  }, []);

  useE(() => {
    const onKey = (e) => { if (e.key === "Escape") setPanelOpen(false); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  const store = usePortfolioStore(auth === "in");

  const scrollTop = () => { if (mainRef.current) mainRef.current.scrollTop = 0; };
  const navigate = (id) => { setStock(null); setScreen(id); requestAnimationFrame(scrollTop); };
  const openStock = (t) => { setStock(t); requestAnimationFrame(scrollTop); };
  const onLogin = (res) => { setUser(res.user || null); setAuth("in"); if (res.must_rotate) setScreen("settings"); };
  const logout = async () => { try { await API.logout(); } catch {} setAuth("out"); setUser(null); setScreen("overview"); setStock(null); };

  const doRefresh = async () => {
    setRefreshing(true);
    try { await API.refreshPortfolio(); } catch {}
    await store.reload();
    setRefreshing(false);
  };

  if (auth === "checking") {
    return <div style={{ height: "100%", display: "grid", placeItems: "center", background: "var(--bg-app)" }}>
      <Col gap={14} align="center"><Logo size={40} /><Icon name="loader" size={20} className="spin" style={{ color: "var(--sage-500)" }} /></Col>
    </div>;
  }
  if (auth === "out") return <Login onLogin={onLogin} theme={theme} onToggleTheme={toggleTheme} />;

  const screens = {
    today: window.Today,
    overview: window.Dashboard,
    portfolio: window.Portfolio,
    research: window.Research,
    recommendations: window.Recommendations,
    hermes: window.HermesPage,
    settings: window.Settings,
    system: window.SystemStatus,
  };
  const Current = screens[screen] || window.Dashboard;
  const common = { theme, onNavigate: navigate, onOpenStock: openStock, onOpenHermes: () => setPanelOpen(true), store, user };

  return (
    <div style={{ display: "flex", height: "100%", overflow: "hidden" }}>
      <Sidebar active={screen} onNavigate={navigate} onLogout={logout} user={user} />
      <div style={{ flex: 1, display: "flex", flexDirection: "column", minWidth: 0 }}>
        <TopBar theme={theme} onToggleTheme={toggleTheme} onOpenHermes={() => setPanelOpen(true)}
          summary={store.data && store.data.summary} asOf={store.data && store.data.asOf}
          onRefresh={doRefresh} refreshing={refreshing} />
        <main ref={mainRef} className="scroll-nice" style={{ flex: 1, overflowY: "auto", overflowX: "hidden" }}>
          <div style={{ maxWidth: "var(--content-max)", margin: "0 auto", padding: "28px 28px 80px" }}>
            {stock
              ? <window.StockDetail ticker={stock} store={store} onBack={() => setStock(null)} onOpenStock={openStock} onNavigate={navigate} onOpenHermes={() => setPanelOpen(true)} theme={theme} />
              : <Current {...common} />}
          </div>
        </main>
      </div>
      <HermesLauncher onClick={() => setPanelOpen(true)} hidden={panelOpen || screen === "hermes"} />
      <HermesPanel open={panelOpen} onClose={() => setPanelOpen(false)} />
    </div>
  );
}

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