// Shell: topbar + sidebar + main
const { useMemo } = React;

function Topbar({ nodes, search, setSearch, live, toggleLive, currentUser, onOpenProfile }) {
  const counts = useMemo(() => {
    const c = { ok: 0, warn: 0, crit: 0, off: 0, maint: 0, unknown: 0 };
    for (const n of nodes) {
      if (c[n.status] === undefined) c[n.status] = 0;
      c[n.status]++;
    }
    return c;
  }, [nodes]);
  const avgLat = useMemo(() => {
    const live = nodes.filter(n => n.status !== 'off');
    return live.reduce((s, n) => s + n.latency, 0) / (live.length || 1);
  }, [nodes]);

  // Hamburger toggles a body class — CSS handles the rest.
  // Kept out of React state because it's purely a transient UI flag
  // and we don't need re-renders when it flips.
  function toggleSidebar() {
    document.body.classList.toggle('sb-open');
  }
  function closeSidebar() {
    document.body.classList.remove('sb-open');
  }
  // Clicking the scrim (pseudo-element covering the rest of the page
  // on mobile when the sidebar is open) should close the sidebar.
  React.useEffect(() => {
    function onClick(e) {
      if (!document.body.classList.contains('sb-open')) return;
      // If the click falls outside the sidebar AND outside the hamburger,
      // treat it as a scrim tap.
      if (e.target.closest('.sidebar') || e.target.closest('.hamburger')) return;
      closeSidebar();
    }
    document.addEventListener('click', onClick);
    return () => document.removeEventListener('click', onClick);
  }, []);

  return (
    <div className="topbar">
      <button className="hamburger" aria-label="menu" onClick={toggleSidebar}>☰</button>
      <div className="brand">
        <div className="brand-logo" />
        <div>
          <div className="brand-name">МОНИТОРИНГ · СИТНОВ</div>
          <div className="brand-sub">{nodes.length} endpoints · prod</div>
        </div>
      </div>
      <div className="topbar-section">
        <span className="tick-dot" />
        <span className="topbar-label">Live</span>
        <span className="topbar-val">{live ? 'streaming' : 'paused'}</span>
      </div>
      <div className="topbar-section hide-mobile">
        <span className="topbar-label">Up</span>
        <span className="topbar-val ok">{counts.ok}</span>
        <span className="topbar-label" style={{marginLeft:6}}>Warn</span>
        <span className="topbar-val warn">{counts.warn}</span>
        <span className="topbar-label" style={{marginLeft:6}}>Down</span>
        <span className="topbar-val crit">{counts.crit}</span>
        <span className="topbar-label" style={{marginLeft:6}}>Off</span>
        <span className="topbar-val" style={{color:'var(--text-dim)'}}>{counts.off}</span>
        <span className="topbar-label" style={{marginLeft:6}}>Maint</span>
        <span className="topbar-val warn">{counts.maint}</span>
      </div>
      <div className="topbar-section hide-mobile">
        <span className="topbar-label">avg</span>
        <span className="topbar-val">{avgLat.toFixed(0)}ms</span>
      </div>
      <div className="topbar-section grow hide-mobile">
        <div className="search">
          <span style={{color:'var(--text-mute)'}}>›</span>
          <input
            placeholder="filter · group:cloudflare status:crit askdento"
            value={search}
            onChange={e => setSearch(e.target.value)}
          />
          <kbd>⌘K</kbd>
        </div>
      </div>
      <div className="topbar-section">
        <span className="topbar-label">Tick</span>
        <button className="btn" onClick={toggleLive} style={{padding:'3px 8px'}}>
          {live ? 'pause' : 'resume'}
        </button>
      </div>
      <div className="topbar-section" style={{borderRight:0}}>
        {currentUser && (
          <>
            <span className="topbar-label hide-mobile">User</span>
            <span className="topbar-val hide-mobile">{currentUser.username}</span>
            {currentUser.isAdmin && <span className="chip accent hide-mobile" style={{fontSize: 9}}>admin</span>}
            <button className="btn hide-mobile" onClick={onOpenProfile} style={{padding:'3px 8px'}}>change pw</button>
            <button className="btn" onClick={() => window.signOut && window.signOut()} style={{padding:'3px 8px'}}>
              sign out
            </button>
          </>
        )}
      </div>
    </div>
  );
}

function Sidebar({ view, setView, nodes, alerts, currentUser, isViewAllowed }) {
  const critCount = alerts.filter(a => a.severity === 'crit' && !a.ack).length;
  const warnCount = alerts.filter(a => a.severity === 'warn' && !a.ack).length;
  const allItems = [
    { id: 'overview', label: 'Overview',   idx: '01' },
    { id: 'threed',   label: '3D Fleet',   idx: '02' },
    { id: 'topology', label: 'Topology',   idx: '03' },
    { id: 'nodes',    label: 'Endpoints',  idx: '04', count: nodes.length },
    { id: 'alerts',   label: 'Alerts',     idx: '05', count: critCount + warnCount },
    { id: 'logs',     label: 'Logs',       idx: '06' },
    { id: 'admin',    label: 'Admin',      idx: '07' },
    { id: 'notifications', label: 'Notifications', idx: '08' },
    { id: 'users',    label: 'Users',      idx: '09' },
    { id: 'history',  label: 'History',    idx: '10' },
  ];
  // Filter by the current user's permissions. If the app hasn't told
  // us yet (no currentUser / no helper), fall back to showing all —
  // this branch shouldn't run because the login gate blocks it, but
  // we stay defensive.
  const allow = typeof isViewAllowed === 'function' ? isViewAllowed : () => true;
  const items = allItems.filter(i => allow(i.id));
  const byGroup = {};
  for (const n of nodes) byGroup[n.group] = (byGroup[n.group] || 0) + 1;
  const liveGroups = window.deriveGroups ? window.deriveGroups(nodes) : window.GROUPS;

  return (
    <aside className="sidebar">
      <div className="sidebar-section">Views</div>
      {items.map(i => (
        <button
          key={i.id}
          className={`nav-item ${view === i.id ? 'active' : ''}`}
          onClick={() => {
            setView(i.id);
            // On mobile the sidebar is an overlay — auto-close after selection.
            document.body.classList.remove('sb-open');
          }}
        >
          <span className="idx">{i.idx}</span>
          <span>{i.label}</span>
          {i.count != null && <span className="count">{i.count}</span>}
        </button>
      ))}
      <div className="sidebar-section" style={{marginTop: 8}}>Groups</div>
      <div style={{padding:'0 12px 12px'}}>
        {liveGroups.map(g => (
          <div key={g} className="mini-stat"><span>{g}</span><span>{byGroup[g] || 0}</span></div>
        ))}
      </div>
      <div className="sidebar-foot">
        <div className="mini-stat"><span>build</span><span>#8f2a91c</span></div>
        <div className="mini-stat"><span>viewer</span><span>{currentUser?.username || '—'}</span></div>
      </div>
    </aside>
  );
}

Object.assign(window, { Topbar, Sidebar });
