// ============================================================
// Sidebar.jsx
// ============================================================
// FASE 53.4 (sessione 58) — `alerts` count è dinamico: legge `anomaly_flag.state=open`
// del tenant corrente via /api/anomaly-flags?limit=1 e usa kpi.byState.open.
// Fallback al count seed se fetch fallisce.
//
// Quick win sessione 63 — Broadcast event `anomaly_count_changed`: oltre al
// polling 60s + change route, la Sidebar ascolta un window event emesso dai
// FE che fanno PATCH `/api/anomaly-flags/[id]` (Alerts.jsx + AnomalyResolveModal
// in Customizing). Refresh on-demand: l'utente vede il count aggiornato subito
// dopo Ack/Risolvi/Riapri (max delay ~ runtime fetch, non più 60s).
const NAV_GROUPS = [
  {
    label: 'Operations',
    items: [
      { id: 'dashboard', label: 'Dashboard', icon: 'dashboard' },
      { id: 'projects', label: 'Progetti CAPEX', icon: 'projects', count: 12 },
      { id: 'workflow', label: 'Workflow CAPEX', icon: 'workflow' },
      { id: 'alerts', label: 'Le mie attività', icon: 'alerts', alert: true, dynamicCount: 'anomalyOpen' },
      { id: 'communications', label: 'Comunicazioni', icon: 'comm' },
    ],
  },
  {
    label: 'Procurement',
    items: [
      { id: 'rda', label: 'Richieste di Acquisto', icon: 'rda', count: 10 },
      { id: 'oda', label: 'Ordini di Acquisto', icon: 'rda', count: 2 },
      { id: 'benchmark', label: 'Benchmark offerte', icon: 'benchmark' },
      { id: 'vendors', label: 'Vendor management', icon: 'vendors', count: 17 },
    ],
  },
  {
    label: 'Knowledge',
    items: [
      { id: 'archive', label: 'Archivio storico', icon: 'archive' },
      { id: 'documents', label: 'Documenti & specifiche', icon: 'docs' },
      { id: 'aichat', label: 'AI Assistant', icon: 'sparkle' },
    ],
  },
  {
    label: 'Governance',
    items: [
      { id: 'reports', label: 'Reportistica', icon: 'reports' },
      { id: 'audit', label: 'Audit log', icon: 'audit' },
      { id: 'customizing', label: 'Customizing', icon: 'sliders' },
      { id: 'settings', label: 'Impostazioni', icon: 'settings' },
    ],
  },
];

function Sidebar() {
  const { route, navigate, user, setUser, seed, seedCustom, setCopilotOpen } = useStore();
  // FASE 53.4 (sessione 58) — Real count anomaly_flag open via API
  const [anomalyOpenCount, setAnomalyOpenCount] = React.useState(null);
  // FASE 16 (sessione 91) — Count task personali (firme + approvazioni) da
  // /api/my-tasks. Il badge "Alert & Early warning" somma anomalie + task,
  // così l'utente vede a colpo d'occhio quante cose ha da fare.
  const [myTasksCount, setMyTasksCount] = React.useState(null);

  React.useEffect(() => {
    // Niente polling finché l'utente non è noto: evita un fetch sprecato
    // (senza X-Actor-Persona-Id) al primo render, prima dell'idratazione auth.
    if (!user?.id) return;
    let cancelled = false;
    const headers = { 'X-Actor-Persona-Id': user.id };
    async function fetchCounts() {
      try {
        const r = await fetch('/api/anomaly-flags?limit=1', {
          credentials: 'same-origin', cache: 'no-store', headers,
        });
        if (r.ok) {
          const j = await r.json();
          if (!cancelled) setAnomalyOpenCount(j.kpi?.byState?.open ?? 0);
        }
      } catch { /* badge resta nascosto */ }
      try {
        const r = await fetch('/api/my-tasks', {
          credentials: 'same-origin', cache: 'no-store', headers,
        });
        if (r.ok) {
          const j = await r.json();
          if (!cancelled) setMyTasksCount(j.count ?? 0);
        }
      } catch { /* badge resta nascosto */ }
    }
    fetchCounts();
    // Rete di sicurezza ogni 60s. Il refresh tempestivo è event-driven (sotto):
    // i count cambiano solo via azioni utente → niente re-fetch a ogni navigazione.
    const interval = setInterval(fetchCounts, 60_000);
    // Refresh on-demand: anomaly_count_changed (PATCH anomaly-flags) +
    // my_tasks_changed (firma completata / task evaso). Evita lag fino a 60s.
    window.addEventListener('anomaly_count_changed', fetchCounts);
    window.addEventListener('my_tasks_changed', fetchCounts);
    return () => {
      cancelled = true;
      clearInterval(interval);
      window.removeEventListener('anomaly_count_changed', fetchCounts);
      window.removeEventListener('my_tasks_changed', fetchCounts);
    };
  }, [user?.id]);

  function resolveCount(it) {
    if (it.dynamicCount === 'anomalyOpen') {
      if (anomalyOpenCount == null && myTasksCount == null) return null;
      return (anomalyOpenCount ?? 0) + (myTasksCount ?? 0);
    }
    return it.count;
  }

  return (
    <aside className="sidebar">
      {NAV_GROUPS.map((g) => {
        // FASE 16 (sessione 93) — RBAC: mostra solo le voci permesse dal
        // ruolo dell'utente (canAccessRoute legge role.permissions via
        // seedCustom). Gruppo senza voci visibili → nascosto del tutto.
        // Fail-open: se permissions.jsx non è caricato → mostra tutto (mai
        // crashare la Sidebar per un global mancante).
        const items = g.items.filter((it) =>
          (typeof canAccessRoute === 'function')
            ? canAccessRoute(it.id, user, seedCustom)
            : true);
        if (items.length === 0) return null;
        return (
        <div className="group" key={g.label}>
          <div className="group-label">{g.label}</div>
          {items.map((it) => {
            const c = resolveCount(it);
            return (
              <div
                key={it.id}
                className={`nav-item ${route === it.id ? 'active' : ''} ${it.alert ? 'alert' : ''}`}
                onClick={() => {
                  if (it.id === 'aichat') { setCopilotOpen(true); return; }
                  navigate(it.id);
                }}
              >
                <Icon name={it.icon} size={15} />
                <span className="label">{it.label}</span>
                {c != null && c > 0 && <span className="count">{c}</span>}
              </div>
            );
          })}
        </div>
        );
      })}
      {user && (
        <div className="role-switch">
          <div style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: '0.12em' }}>Switch ruolo · demo</div>
          <window.Autocomplete
            value={user.id}
            onChange={(v) => { const p = seed.PERSONAS.find((x) => x.id === v); if (p) setUser(p); }}
            allowClear={false}
            options={seed.PERSONAS.map((p) => ({ value: p.id, label: p.name, sublabel: p.role }))}
            placeholder="Cerca persona… (spazio per lista)"
            testId="sidebar-roleswitch-ac"
          />
        </div>
      )}
      <div style={{ marginTop: 'auto', padding: '10px 14px 12px', fontSize: 9.5, fontFamily: 'var(--font-mono)', color: 'var(--text-3)', textAlign: 'center', textTransform: 'uppercase', letterSpacing: '0.14em', borderTop: '1px solid var(--line)' }}>
        by Leaven Consulting
      </div>
    </aside>
  );
}
Object.assign(window, { Sidebar });
