// ============================================================
// App.jsx — root
// ============================================================
function App() {
  const { user, theme, route, toasts, sidebarCollapsed, copilotOpen, seedCustom } = useStore();

  // Sessione 84 (gap #4) — Onboarding wizard se tenant ha 0 projects.
  // Detect: fetch /api/projects, se length===0 mostra wizard fullscreen.
  // Dismiss persiste in sessionStorage (no localStorage → ri-detection a logout).
  const [needsOnboarding, setNeedsOnboarding] = React.useState(null); // null=loading, false=skip, true=show
  React.useEffect(() => {
    if (!user) { setNeedsOnboarding(null); return; }
    const dismissedKey = `lgs.onboarding.dismissed.${user.id}`;
    if (sessionStorage.getItem(dismissedKey) === '1') {
      setNeedsOnboarding(false);
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        const r = await fetch('/api/projects?limit=1', { headers: { 'X-Actor-Persona-Id': user.id } });
        if (!r.ok) { if (!cancelled) setNeedsOnboarding(false); return; }
        const j = await r.json();
        const projects = Array.isArray(j) ? j : (Array.isArray(j.data) ? j.data : []);
        if (!cancelled) setNeedsOnboarding(projects.length === 0);
      } catch { if (!cancelled) setNeedsOnboarding(false); }
    })();
    return () => { cancelled = true; };
  }, [user?.id]);

  React.useEffect(() => {
    document.body.className = theme === 'light' ? 'theme-light' : 'theme-dark';
  }, [theme]);

  if (!user) return <Login />;

  // Mostra wizard se tenant nuovo (0 projects e non dismissed).
  if (needsOnboarding === true) {
    return (
      <OnboardingWizard onComplete={() => {
        sessionStorage.setItem(`lgs.onboarding.dismissed.${user.id}`, '1');
        setNeedsOnboarding(false);
      }}/>
    );
  }

  let page = null;
  if (route === 'dashboard') page = <Dashboard/>;
  else if (route === 'projects') page = <Projects/>;
  else if (route === 'project_detail') page = <ProjectDetail/>;
  else if (route === 'workflow') page = <Workflow/>;
  else if (route === 'archive') page = <Archive/>;
  else if (route === 'rda') page = <RdA/>;
  else if (route === 'oda') page = <Oda/>;
  else if (route === 'benchmark') page = <Benchmark/>;
  else if (route === 'communications') page = <Communications/>;
  else if (route === 'documents') page = <Documents/>;
  else if (route === 'vendors') page = <Vendors/>;
  else if (route === 'reports') page = <Reports/>;
  else if (route === 'alerts') page = <Alerts/>;
  else if (route === 'audit') page = <Audit/>;
  else if (route === 'customizing') page = <Customizing/>;
  else if (route === 'settings') page = <Settings/>;
  else page = <Dashboard/>;

  // FASE 16 (sessione 93) — RBAC guardia di rotta: se l'utente raggiunge una
  // pagina non permessa dal suo ruolo (es. routeParam persistito in
  // localStorage, o cambio ruolo) ripiega sulla Dashboard. La Sidebar già
  // nasconde le voci; questa è la difesa lato rotta.
  if (typeof canAccessRoute === 'function' && route !== 'dashboard'
      && !canAccessRoute(route, user, seedCustom)) {
    page = <Dashboard/>;
  }

  return (
    <div className={`app-shell${sidebarCollapsed ? ' collapsed' : ''}`}>
      <Topbar/>
      <Sidebar/>
      <div className={`main${copilotOpen ? ' with-copilot' : ''}`}>
        {page}
        <Copilot/>
      </div>
      <CommandPalette/>
      <ToastLayer toasts={toasts}/>
    </div>
  );
}

function ToastLayer({ toasts }) {
  return (
    <div style={{position:'fixed', right:20, bottom:20, display:'flex', flexDirection:'column', gap:8, zIndex:9999}}>
      {toasts.map(t => (
        <div key={t.id} className={`toast ${t.tone||''}`}>
          <div className="ttl">{t.title}</div>
          {t.desc && <div className="desc">{t.desc}</div>}
        </div>
      ))}
    </div>
  );
}

// FASE 52 — fetch wrapper globale: SUPERADMIN may set lgs.actingTenantId in
// localStorage to view another tenant's data. Wrapper inietta automaticamente
// header X-Acting-Tenant-Id su ogni fetch a /api/*. BE ignora silently se
// caller non è SUPERADMIN (vedi lib/tenant.ts resolveActingTenantId).
(function installActingTenantFetchWrapper() {
  if (window.__actingTenantFetchInstalled) return;
  window.__actingTenantFetchInstalled = true;
  const origFetch = window.fetch.bind(window);
  window.fetch = function (input, init) {
    try {
      const url = typeof input === 'string' ? input : (input && input.url) || '';
      if (url.startsWith('/api/')) {
        const acting = localStorage.getItem('lgs.actingTenantId');
        if (acting) {
          init = init || {};
          const h = init.headers instanceof Headers
            ? Object.fromEntries(init.headers.entries())
            : { ...(init.headers || {}) };
          if (!h['X-Acting-Tenant-Id'] && !h['x-acting-tenant-id']) {
            h['X-Acting-Tenant-Id'] = acting;
          }
          init.headers = h;
        }
      }
    } catch { /* swallow */ }
    return origFetch(input, init);
  };
})();

// FASE 2 — aspetta che seed.jsx abbia completato il fetch a /api/bootstrap
// prima di montare React. Così il primo render usa già i dati dal DB.
(async () => {
  try {
    if (window.__SEED_READY) await window.__SEED_READY;
  } catch (err) {
    console.error('[Veridanto] impossibile caricare i dati dal BE, proseguo con placeholder vuoti', err);
  }
  // FASE 2b.AI — pulisce eventuali chiavi residue in localStorage da versioni precedenti.
  if (typeof window.cleanLocalAiKeys === 'function') window.cleanLocalAiKeys();
  const root = ReactDOM.createRoot(document.getElementById('root'));
  root.render(
    <StoreProvider>
      <App/>
    </StoreProvider>
  );
})();
