/* Voyage Fleet — app root: router, breadcrumbs, global search. */

const { useState: useS_app, useEffect: useEf_app } = React;

/* ─── Global search (⌘K) ───────────────────────────────────────────────── */
function GlobalSearch({ open, onClose }) {
  const [q, setQ] = useS_app("");
  if (!open) return null;
  const ql = q.toLowerCase();
  const tenants = q ? window.FLEET.TENANTS.filter(t => t.slug.includes(ql) || t.name.toLowerCase().includes(ql)).slice(0, 6) : window.FLEET.TENANTS.slice(0, 5);
  const modules = q ? window.FLEET.MODULES.filter(m => m.id.includes(ql) || m.name.includes(ql) || m.display.toLowerCase().includes(ql)).slice(0, 5) : [];
  const go = fn => { onClose(); fn(); };
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "var(--jrni-color-surface-overlay)", zIndex: 200, display: "flex", alignItems: "flex-start", justifyContent: "center", paddingTop: "12vh" }}>
      <div onClick={e => e.stopPropagation()} style={{ width: 580, maxWidth: "90vw", background: "white", borderRadius: 12, boxShadow: "var(--jrni-shadow-lg)", overflow: "hidden" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "0 16px", height: 52, borderBottom: "1px solid var(--jrni-color-surface-border)" }}>
          <Icons.Search size={16} color="var(--jrni-color-neutral-3)" />
          <input autoFocus value={q} onChange={e => setQ(e.target.value)} placeholder="Search tenants, components, audit…" style={{ flex: 1, border: "none", outline: "none", fontSize: 15, fontFamily: "var(--jrni-font-family-sans)", color: "var(--jrni-color-neutral-1)" }} />
          <span style={{ fontSize: 11, color: "var(--jrni-color-text-soft)", border: "1px solid var(--jrni-color-surface-border)", borderRadius: 4, padding: "2px 7px", fontFamily: "var(--jrni-font-family-mono)" }}>Esc</span>
        </div>
        <div style={{ maxHeight: "52vh", overflowY: "auto", padding: 8 }}>
          {tenants.length ? <div style={searchGroupLabel}>Tenants</div> : null}
          {tenants.map(t => (
            <button key={t.slug} onClick={() => go(() => navigate("/tenant", { slug: t.slug }))} style={searchRow}>
              <Icons.Building size={15} color="var(--jrni-color-text-soft)" />
              <span style={{ fontFamily: "var(--jrni-font-family-mono)", fontWeight: 600, color: "var(--jrni-color-neutral-1)", fontSize: 13.5 }}>{t.slug}</span>
              <span style={{ fontSize: 12.5, color: "var(--jrni-color-text-soft)" }}>{t.name}</span>
              <span style={{ marginLeft: "auto" }}><DriftPill level={t.drift} /></span>
            </button>
          ))}
          {modules.length ? <div style={searchGroupLabel}>Components</div> : null}
          {modules.map(m => (
            <button key={m.id} onClick={() => go(() => navigate("/modules", { id: m.id }))} style={searchRow}>
              <Icons.Module size={15} color="var(--jrni-color-text-soft)" />
              <span style={{ fontWeight: 600, color: "var(--jrni-color-neutral-1)", fontSize: 13.5 }}>{m.display}</span>
              <span style={{ fontFamily: "var(--jrni-font-family-mono)", fontSize: 12, color: "var(--jrni-color-text-soft)" }}>{m.name}</span>
              <span style={{ marginLeft: "auto", fontSize: 12, color: "var(--jrni-color-text-soft)" }}>{m.tenants} tenants</span>
            </button>
          ))}
          {!tenants.length && !modules.length ? <div style={{ padding: 24, textAlign: "center", color: "var(--jrni-color-text-soft)", fontSize: 13.5 }}>No matches for “{q}”.</div> : null}
        </div>
      </div>
    </div>
  );
}
const searchGroupLabel = { fontSize: 10.5, fontWeight: 700, color: "var(--jrni-color-neutral-3)", textTransform: "uppercase", letterSpacing: 0.05, padding: "8px 10px 4px" };
const searchRow = { display: "flex", alignItems: "center", gap: 10, width: "100%", padding: "9px 10px", borderRadius: 8, border: "none", background: "transparent", cursor: "pointer", fontFamily: "var(--jrni-font-family-sans)", textAlign: "left" };

/* ─── Breadcrumb + active-nav resolution ───────────────────────────────── */
function resolve(route) {
  const { path, params } = route;
  const home = { label: "Fleet", path: "/" };
  switch (path) {
    case "/":         return { active: "overview", trail: [home, { label: "Overview" }], screen: <FleetOverview params={params} /> };
    case "/tenants":  return { active: "tenants",  trail: [home, { label: "All Tenants" }], screen: <FleetOverview params={params} /> };
    case "/tenant":   {
      const t = window.FLEET.tenantBySlug(params.slug);
      if (!t) return { active: "tenants", trail: [home, { label: "Tenants", path: "/tenants" }, { label: "Not found" }], screen: <NotFound title={`Tenant "${params.slug || ""}" not found`} body="It may have been archived or the slug may be misspelled." actions={<React.Fragment><Button variant="primary" icon={<Icons.Gauge size={13} />} onClick={() => navigate("/")}>Back to Fleet Overview</Button><Button variant="secondary" icon={<Icons.Search size={13} />} onClick={() => window.dispatchEvent(new CustomEvent("vf-open-search"))}>Search the fleet</Button></React.Fragment>} /> };
      return { active: "tenants", trail: [home, { label: "Tenants", path: "/tenants" }, { label: t.slug }], screen: <TenantDetail params={params} /> };
    }
    case "/new":      return { active: "new", trail: [home, { label: "New Tenant" }], screen: <NewTenantWizard params={params} /> };
    case "/drift":    return { active: "drift", trail: [home, { label: "Drift Report" }], screen: <DriftReport params={params} /> };
    case "/modules":  return { active: "modules", trail: [home, { label: "Catalog", path: "/modules" }, { label: "Components" }], screen: <ModulesCatalog params={params} /> };
    case "/audit":    return { active: "audit", trail: [home, { label: "Operations" }, { label: "Audit Log" }], screen: <AuditLog params={params} /> };
    case "/settings": return { active: "settings", trail: [home, { label: "Settings" }], screen: <Settings params={params} /> };
    default:          return { active: "overview", trail: [home, { label: "Overview" }], screen: <FleetOverview params={params} /> };
  }
}

function App() {
  const route = useRoute();
  const [searchOpen, setSearchOpen] = useS_app(false);
  const [role, setRoleState] = useS_app(window.FLEET.ROLE);

  // Apply fleet-size override (P3) before resolving the screen.
  window.FLEET.applySize(route.params.fleet);

  const setRole = (r) => { window.FLEET.setRole(r); setRoleState(r); };

  useEf_app(() => {
    const onKey = e => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setSearchOpen(o => !o); }
      if (e.key === "Escape") setSearchOpen(false);
    };
    const onOpenSearch = () => setSearchOpen(true);
    window.addEventListener("keydown", onKey);
    window.addEventListener("vf-open-search", onOpenSearch);
    return () => { window.removeEventListener("keydown", onKey); window.removeEventListener("vf-open-search", onOpenSearch); };
  }, []);

  const { active, trail, screen } = resolve(route);
  return (
    <React.Fragment>
      <AppShell active={active} trail={trail} onOpenSearch={() => setSearchOpen(true)} role={role} onSetRole={setRole}>
        {screen}
      </AppShell>
      <GlobalSearch open={searchOpen} onClose={() => setSearchOpen(false)} />
    </React.Fragment>
  );
}

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