// ============================================================
// Projects.jsx — full portfolio list with filters
// ============================================================
// Sessione 65 / Dashboard — Brief severity color mapping condiviso.
const PROJECTS_BRIEF_SEVERITY_TONES = { ok: 'ok', warning: 'warn', critical: 'err' };
const PROJECTS_BRIEF_SEVERITY_LABELS = { ok: 'in linea', warning: 'attenzione', critical: 'critica' };

function Projects() {
  const { navigate, seed, extras, pushToast, user, seedCustom } = useStore();
  // FASE 2 RBAC (sessione 102) — capability gating "+ Nuovo progetto".
  const canCreateProject = window.can('project.create', user, seedCustom);
  const [filter, setFilter] = React.useState({ site: '', phase: '', health: '', q: '' });
  const [view, setView] = React.useState('table');
  const [showNew, setShowNew] = React.useState(false);
  // Sessione 87 — "Chiedi all'AI" collega PORTFOLIO_BRIEFER (stesso pattern di Dashboard).
  // Modale persistente: apre IMMEDIATAMENTE al click in stato loading. Non chiude mai
  // automaticamente, mostra success/error/loading dentro al modale (no toast volatili).
  const [briefState, setBriefState] = React.useState('idle'); // idle | loading | success | error
  const [briefResult, setBriefResult] = React.useState(null);
  const [briefError, setBriefError] = React.useState(null); // { status, detail, raw }
  const briefBusy = briefState === 'loading';

  async function handleAskAi() {
    if (briefBusy) return;
    setBriefState('loading');
    setBriefResult(null);
    setBriefError(null);
    try {
      const aiOverrideHeaders = (() => {
        try {
          if (!user?.id) return {};
          const raw = localStorage.getItem(`lgs.ai.user.${user.id}.preferences`);
          if (!raw) return {};
          const j = JSON.parse(raw);
          const headers = {};
          if (j?.modeOverride && j.modeOverride !== 'default') headers['X-AI-Mode-Override'] = j.modeOverride;
          if (j?.providerOverride && j.providerOverride !== 'default') headers['X-AI-Provider-Override'] = j.providerOverride;
          return headers;
        } catch { return {}; }
      })();
      const r = await fetch('/api/ai/portfolio-briefer/run', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(user?.id ? { 'X-Actor-Persona-Id': user.id } : {}),
          ...aiOverrideHeaders,
        },
        credentials: 'same-origin',
        body: JSON.stringify({}),
      });
      const j = await r.json().catch(() => ({}));
      if (!r.ok) {
        setBriefError({
          status: r.status,
          detail: j?.detail === 'no_ai_provider_configured'
            ? 'Nessun provider AI configurato. Imposta una API key in Customizing > AI.'
            : (j?.detail || j?.error || `HTTP ${r.status}`),
          raw: j,
        });
        setBriefState('error');
        return;
      }
      setBriefResult(j);
      setBriefState('success');
    } catch (e) {
      setBriefError({ status: 0, detail: `Errore rete: ${String(e?.message || e)}`, raw: null });
      setBriefState('error');
    }
  }

  function closeBriefModal() {
    setBriefState('idle');
    setBriefResult(null);
    setBriefError(null);
  }
  // FASE rebrand-test: dedup extras + seed per evitare key duplicate in tabella.
  // Quando un progetto creato in sessione (extras) ha lo stesso id di uno già in DB
  // (refresh dopo bootstrap), `extras` vince sul `seed`.
  const allProjects = React.useMemo(() => {
    const ext = extras?.projects || [];
    const seenIds = new Set();
    const out = [];
    for (const p of [...ext, ...seed.PROJECTS]) {
      if (!p?.id || seenIds.has(p.id)) continue;
      seenIds.add(p.id);
      out.push(p);
    }
    return out;
  }, [extras, seed]);

  const filtered = allProjects.filter((p) => {
    if (filter.site && p.site !== filter.site) return false;
    if (filter.phase && p.phase !== filter.phase) return false;
    if (filter.health && p.health !== filter.health) return false;
    if (filter.q && !(p.name.toLowerCase().includes(filter.q.toLowerCase()) || p.code.toLowerCase().includes(filter.q.toLowerCase()))) return false;
    return true;
  });
  const pg = usePaginated(filtered, 10);
  React.useEffect(() => { pg.setPage(1); }, [filter.site, filter.phase, filter.health, filter.q]);

  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <div className="eyebrow">Portfolio</div>
          <h1 className="page-title">Progetti CAPEX</h1>
          <div className="page-sub">{filtered.length} progetti su {allProjects.length} totali. Clicca un progetto per aprire scheda con Gantt, forecast EV, comunicazioni e agente suggerimenti.</div>
        </div>
        <div className="actions">
          <div style={{ display: 'flex', border: '1px solid var(--line)', borderRadius: 6, overflow: 'hidden' }}>
            <button className={`btn sm ghost ${view==='table'?'':''}`} style={{ borderRadius: 0, background: view==='table' ? 'var(--bg-2)' : 'transparent' }} onClick={() => setView('table')}><Icon name="grid" size={12}/></button>
            <button className={`btn sm ghost`} style={{ borderRadius: 0, background: view==='gantt' ? 'var(--bg-2)' : 'transparent' }} onClick={() => setView('gantt')}><Icon name="gantt" size={12}/></button>
          </div>
          <Btn
            variant={canCreateProject ? 'primary' : 'ghost'}
            size="sm"
            disabled={!canCreateProject}
            onClick={() => { if (canCreateProject) setShowNew(true); }}
            title={canCreateProject ? undefined : window.whyDisabled('project.create')}
          ><Icon name="plus" size={12}/> Nuovo progetto</Btn>
        </div>
      </div>

      <div className="card" style={{ marginBottom: 14 }}>
        <div className="card-body tight row" style={{ gap: 10, flexWrap: 'wrap' }}>
          <div className="row" style={{ gap: 6, padding: '4px 10px', border: '1px solid var(--line)', borderRadius: 6, background: 'var(--bg-2)', minWidth: 220 }}>
            <Icon name="search" size={12} />
            <input placeholder="Cerca per nome o codice…" value={filter.q} onChange={(e) => setFilter({ ...filter, q: e.target.value })} style={{ background: 'transparent', border: 'none', outline: 'none', flex: 1, fontSize: 12 }} />
          </div>
          <Select label="Sito" value={filter.site} onChange={(v) => setFilter({ ...filter, site: v })} options={['', ...seed.SITES]} />
          <Select label="Fase" value={filter.phase} onChange={(v) => setFilter({ ...filter, phase: v })} options={['', 'requisito', 'pianificazione', 'offerta', 'rda', 'esecuzione', 'chiusura']} />
          <Select label="Health" value={filter.health} onChange={(v) => setFilter({ ...filter, health: v })} options={['', 'ok', 'warn', 'err']} />
          <div className="spacer" />
          <Btn variant="ghost" size="sm"><Icon name="filter" size={12}/> Più filtri</Btn>
          <Btn variant="ai" size="sm" onClick={handleAskAi} disabled={briefBusy} data-action="projects-ask-ai">
            <Icon name="sparkle" size={12}/> {briefBusy ? 'AI in corso…' : 'Chiedi all\'AI'}
          </Btn>
        </div>
      </div>

      {view === 'table' ? (
        <div className="card">
          <table className="tbl">
            <thead>
              <tr>
                <th>Codice</th>
                <th>Nome progetto</th>
                <th>Sito</th>
                <th>Categoria</th>
                <th>Fase</th>
                <th style={{ width: 140 }}>Avanzamento</th>
                <th className="num">Budget</th>
                <th className="num">Impegnato</th>
                <th className="num">Speso</th>
                <th>Scadenza</th>
                <th>Health</th>
              </tr>
            </thead>
            <tbody>
              {pg.slice.map((p) => (
                <tr key={p.id} className="clickable" onClick={() => navigate('project_detail', p.id)}>
                  <td className="mono" style={{ color: 'var(--text-2)', fontSize: 11 }}>{p.code}</td>
                  <td style={{ fontWeight: 500 }}>{p.name}</td>
                  <td style={{ color: 'var(--text-2)', fontSize: 11.5 }}>{p.site}</td>
                  <td style={{ color: 'var(--text-2)', fontSize: 11.5 }}>{p.category}</td>
                  <td><PhaseChip phase={p.phase} /></td>
                  <td>
                    <div className="row" style={{ gap: 8 }}>
                      <Meter value={p.progress} tone={p.health === 'err' ? 'err' : p.health === 'warn' ? 'warn' : 'ok'} />
                      <span className="num" style={{ fontSize: 11 }}>{p.progress}%</span>
                    </div>
                  </td>
                  <td className="num">{fmtEUR(p.budget, true)}</td>
                  <td className="num">{fmtEUR(p.committed, true)}</td>
                  <td className="num">{fmtEUR(p.spent, true)}</td>
                  <td className="mono" style={{ fontSize: 11 }}>{fmtDate(p.end)}</td>
                  <td><Health h={p.health} /></td>
                </tr>
              ))}
            </tbody>
          </table>
          <Pagination {...pg} />
        </div>
      ) : (
        <ProjectsGantt projects={filtered} onOpen={(id) => navigate('project_detail', id)} />
      )}
      <NewProjectModal open={showNew} onClose={() => setShowNew(false)} />

      {briefState !== 'idle' && typeof window !== 'undefined' && window.Modal && (
        <window.Modal
          open
          onClose={closeBriefModal}
          title={
            briefState === 'loading'
              ? 'Chiedi all\'AI · elaborazione in corso'
              : briefState === 'error'
              ? 'Chiedi all\'AI · errore'
              : `Brief AI · ${briefResult?.provider}/${briefResult?.model}`
          }
          size="lg"
          footer={
            <>
              {briefState === 'error' && (
                <Btn variant="ai" size="sm" onClick={handleAskAi} data-action="projects-ask-ai-retry">
                  <Icon name="sparkle" size={12}/> Riprova
                </Btn>
              )}
              <Btn variant="ghost" size="sm" onClick={closeBriefModal}>Chiudi</Btn>
            </>
          }
        >
          {briefState === 'loading' && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12, padding: '40px 20px', textAlign: 'center' }} data-brief-state="loading">
              <div style={{ fontSize: 32 }}>✨</div>
              <div style={{ fontSize: 13, fontWeight: 500 }}>L'agente sta analizzando il portfolio…</div>
              <div style={{ fontSize: 11.5, color: 'var(--text-3)', lineHeight: 1.5 }}>
                Carica snapshot progetti + RDA + anomalie, invoca il provider AI configurato,<br/>
                produce sintesi · headline · rischi · azioni raccomandate.<br/>
                Il reasoner può richiedere 10-30 secondi.
              </div>
            </div>
          )}

          {briefState === 'error' && briefError && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }} data-brief-state="error">
              <div style={{ padding: 14, background: 'var(--bg-2)', borderRadius: 6, borderLeft: '3px solid var(--err)' }}>
                <div className="row" style={{ gap: 8, alignItems: 'center', marginBottom: 8 }}>
                  <Chip kind="err" dot>HTTP {briefError.status || 'rete'}</Chip>
                  <span style={{ fontSize: 11, color: 'var(--text-3)' }}>endpoint: /api/ai/portfolio-briefer/run</span>
                </div>
                <div style={{ fontSize: 12.5, lineHeight: 1.6, color: 'var(--text-1)' }}>
                  {briefError.detail}
                </div>
              </div>
              <div>
                <div className="eyebrow">Cosa puoi fare</div>
                <ul style={{ marginTop: 6, paddingLeft: 18, fontSize: 12, lineHeight: 1.7 }}>
                  <li>Premi <strong>Riprova</strong>: il reasoner può fallire la prima volta su JSON e riuscire alla seconda.</li>
                  <li>Verifica in <em>Customizing → AI</em> che ci sia un provider con chiave valida.</li>
                  <li>Se persiste, apri <em>Customizing → AI Tool Executions</em> per audit dettagliato.</li>
                </ul>
              </div>
              {briefError.raw && (
                <details style={{ fontSize: 11, color: 'var(--text-3)' }}>
                  <summary style={{ cursor: 'pointer' }}>Dettaglio tecnico (raw response)</summary>
                  <pre style={{ marginTop: 6, padding: 8, background: 'var(--bg-2)', borderRadius: 4, overflow: 'auto', maxHeight: 200, fontSize: 10.5 }}>
                    {JSON.stringify(briefError.raw, null, 2)}
                  </pre>
                </details>
              )}
            </div>
          )}

          {briefState === 'success' && briefResult && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }} data-brief-state="success">
              <div className="row" style={{ gap: 8, alignItems: 'center' }}>
                <Chip kind={PROJECTS_BRIEF_SEVERITY_TONES[briefResult.brief?.severity] || 'info'} dot>
                  {PROJECTS_BRIEF_SEVERITY_LABELS[briefResult.brief?.severity] || briefResult.brief?.severity}
                </Chip>
                <span style={{ fontSize: 11, color: 'var(--text-3)' }}>
                  Context: {briefResult.ctxSize?.totalProjects ?? 0} progetti · {briefResult.ctxSize?.topRiskProjects ?? 0} top risk · {briefResult.ctxSize?.anomaliesOpen ?? 0} anomalie
                </span>
              </div>

              <div>
                <div className="eyebrow">Sintesi</div>
                <p style={{ fontSize: 12.5, lineHeight: 1.6, marginTop: 6 }}>{briefResult.brief?.summary}</p>
              </div>

              {briefResult.brief?.headlines?.length > 0 && (
                <div>
                  <div className="eyebrow">Headline</div>
                  <ul style={{ marginTop: 6, paddingLeft: 18, fontSize: 12, lineHeight: 1.6 }}>
                    {briefResult.brief.headlines.map((h, i) => <li key={i}>{h}</li>)}
                  </ul>
                </div>
              )}

              {briefResult.brief?.risks?.length > 0 && (
                <div>
                  <div className="eyebrow">Rischi</div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 6 }}>
                    {briefResult.brief.risks.map((r, i) => (
                      <div key={i} style={{ padding: 10, background: 'var(--bg-2)', borderRadius: 4, borderLeft: '3px solid var(--err)' }}>
                        <div style={{ fontSize: 12, fontWeight: 500 }}>{r.title}</div>
                        <div style={{ fontSize: 11.5, marginTop: 4, color: 'var(--text-2)' }}>{r.description}</div>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {briefResult.brief?.actions?.length > 0 && (
                <div>
                  <div className="eyebrow">Azioni raccomandate</div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginTop: 6 }}>
                    {briefResult.brief.actions.map((a, i) => (
                      <div key={i} style={{ padding: 8, background: 'var(--bg-2)', borderRadius: 4, borderLeft: '3px solid var(--info)' }}>
                        <div style={{ fontSize: 12 }}>
                          <strong>{a.title}</strong>
                          {a.owner && <span className="mono" style={{ fontSize: 10.5, color: 'var(--text-3)', marginLeft: 8 }}>· {a.owner}</span>}
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>
          )}
        </window.Modal>
      )}
    </div>
  );
}

function Select({ label, value, onChange, options }) {
  return (
    <div className="row" style={{ gap: 4 }}>
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-2)', textTransform: 'uppercase', letterSpacing: '0.1em' }}>{label}</span>
      <select value={value} onChange={(e) => onChange(e.target.value)} style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', color: 'var(--text-0)', padding: '5px 8px', borderRadius: 6, fontSize: 11.5 }}>
        {options.map((o) => <option key={o} value={o}>{o || 'Tutti'}</option>)}
      </select>
    </div>
  );
}

function ProjectsGantt({ projects, onOpen }) {
  // 12 month window
  const start = new Date('2025-08-01');
  const end = new Date('2026-12-31');
  const totalDays = daysBetween(start, end);
  const months = [];
  const it = new Date(start);
  while (it < end) { months.push(new Date(it)); it.setMonth(it.getMonth() + 1); }
  const today = new Date('2026-04-23');

  return (
    <div className="card">
      <div className="gantt">
        <div className="gantt-row header">
          <div className="label">Progetto · 20</div>
          <div style={{ position: 'relative', height: '100%' }}>
            {months.map((m, i) => {
              const left = (daysBetween(start, m) / totalDays) * 100;
              return <div key={i} style={{ position: 'absolute', left: left + '%', top: 10, fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-3)', borderLeft: '1px solid var(--line)', paddingLeft: 4, height: 'calc(100% - 4px)' }}>{m.toLocaleDateString('it-IT', { month: 'short', year: '2-digit' })}</div>;
            })}
          </div>
        </div>
        {projects.map((p) => {
          const l = (daysBetween(start, new Date(p.start)) / totalDays) * 100;
          const w = (daysBetween(new Date(p.start), new Date(p.end)) / totalDays) * 100;
          const progressW = w * (p.progress / 100);
          const tone = p.health === 'err' ? 'delay' : p.health === 'warn' ? 'risk' : 'done';
          const todayPct = (daysBetween(start, today) / totalDays) * 100;
          return (
            <div key={p.id} className="gantt-row" onClick={() => onOpen(p.id)} style={{ cursor: 'pointer' }}>
              <div className="label">
                <span className="phase-dot" style={{ background: p.health === 'err' ? 'var(--err)' : p.health === 'warn' ? 'var(--warn)' : 'var(--ok)' }} />
                <div>
                  <div style={{ fontSize: 11.5 }}>{p.name}</div>
                  <div className="mono" style={{ fontSize: 10, color: 'var(--text-3)' }}>{p.code}</div>
                </div>
              </div>
              <div className="bars">
                <div className="today" style={{ left: todayPct + '%' }} />
                <div className="bar planned" style={{ left: l + '%', width: w + '%' }} />
                <div className={`bar ${tone}`} style={{ left: l + '%', width: progressW + '%' }}>{p.progress}%</div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { Projects, ProjectsGantt });
