// ============================================================
// Archive.jsx — search archivio LIVE su DB con pgvector + FTS
// FASE 2c.7 (Sprint 5 cliente): full search backend
// ============================================================
function Archive() {
  const { user, pushToast, seedCustom } = useStore();

  // Search state
  const [q, setQ] = React.useState('');
  const [filters, setFilters] = React.useState({});
  const [mode, setMode] = React.useState('hybrid'); // hybrid | semantic | keyword
  const [results, setResults] = React.useState([]);
  const [total, setTotal] = React.useState(0);
  const [facets, setFacets] = React.useState({ docTypeCode: {}, signed: { signed: 0, unsigned: 0 }, project: {} });
  const [searching, setSearching] = React.useState(false);
  const [latencyMs, setLatencyMs] = React.useState(null);
  const [searchedMode, setSearchedMode] = React.useState(null);
  const [parseReasoning, setParseReasoning] = React.useState(null);

  const [selected, setSelected] = React.useState(null);
  const [adhocOpen, setAdhocOpen] = React.useState(false);

  // FASE 14 — bulk reindex state
  const [indexStatus, setIndexStatus] = React.useState(null); // { withFile, indexed, notIndexed, withError, total }
  const [bulkRunning, setBulkRunning] = React.useState(false);
  const [bulkJobs, setBulkJobs] = React.useState([]); // [{ docId, jobId, state? }]
  const [bulkResult, setBulkResult] = React.useState(null);

  const docTypes = (seedCustom?.DOC_TYPES || []);

  // FASE 14 — fetch index status al mount + reload manuale
  const reloadIndexStatus = React.useCallback(async () => {
    try {
      const r = await fetch('/api/documents/reindex-bulk', {
        method: 'GET',
        headers: { 'X-Actor-Persona-Id': user?.id || '' },
        credentials: 'same-origin',
        cache: 'no-store',
      });
      const j = await r.json().catch(() => ({}));
      if (r.ok) setIndexStatus(j.data || null);
    } catch {}
  }, [user?.id]);

  React.useEffect(() => { reloadIndexStatus(); }, [reloadIndexStatus]);

  // FASE 14 — bulk reindex (force=false default → solo missing)
  const runBulkReindex = React.useCallback(async (opts = {}) => {
    if (bulkRunning) return;
    const force = !!opts.force;
    const ok = window.confirm(
      force
        ? `Re-indicizzare TUTTI i documenti con file (anche già indicizzati)? Verranno aggiornati embedding + content_text. Operazione lunga.`
        : `Indicizzare tutti i documenti non ancora indicizzati? I job partono in background (BullMQ).`
    );
    if (!ok) return;
    setBulkRunning(true);
    setBulkResult(null);
    setBulkJobs([]);
    try {
      const r = await fetch('/api/documents/reindex-bulk', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-Actor-Persona-Id': user?.id || '' },
        credentials: 'same-origin',
        body: JSON.stringify({ onlyMissing: !force, force, limit: 500 }),
      });
      const j = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(j?.error || j?.detail || `HTTP ${r.status}`);
      const d = j.data || {};
      setBulkResult(d);
      setBulkJobs((d.jobs || []).filter((x) => !!x.jobId).map((x) => ({ ...x, state: 'queued' })));
      pushToast({
        title: 'Bulk indicizzazione avviata',
        desc: `${d.enqueued} job enqueued, ${d.skipped} skip.`,
        tone: d.enqueued > 0 ? 'ok' : 'info',
      });
      // refresh stato dopo 2s + 8s (fire-and-forget)
      setTimeout(reloadIndexStatus, 2000);
      setTimeout(reloadIndexStatus, 8000);
    } catch (e) {
      pushToast({ title: 'Bulk fallito', desc: String(e?.message || e).slice(0, 200), tone: 'err' });
    } finally {
      setBulkRunning(false);
    }
  }, [user?.id, bulkRunning, pushToast, reloadIndexStatus]);

  // Polling job state (simple): ogni 4s finché ci sono jobs in queued/active.
  React.useEffect(() => {
    if (bulkJobs.length === 0) return;
    const incomplete = bulkJobs.some((j) => !['completed', 'failed', 'not_found'].includes(j.state));
    if (!incomplete) return;
    const t = setTimeout(async () => {
      const updated = await Promise.all(
        bulkJobs.map(async (job) => {
          if (['completed', 'failed', 'not_found'].includes(job.state)) return job;
          try {
            const r = await fetch(`/api/jobs/${encodeURIComponent(job.jobId)}`, { cache: 'no-store' });
            if (!r.ok) return { ...job, state: 'not_found' };
            const j = await r.json();
            return { ...job, state: j.data?.state || 'unknown' };
          } catch {
            return job;
          }
        })
      );
      setBulkJobs(updated);
    }, 4000);
    return () => clearTimeout(t);
  }, [bulkJobs]);

  const runSearch = React.useCallback(async (overrideFilters, overrideQ) => {
    setSearching(true);
    setLatencyMs(null);
    try {
      const body = {
        q: (overrideQ ?? q).trim() || undefined,
        filters: overrideFilters ?? filters,
        mode,
        limit: 30,
        offset: 0,
      };
      const res = await fetch('/api/search', {
        method: 'POST',
        headers: { 'content-type': 'application/json', 'X-Actor-Persona-Id': user?.id || '' },
        body: JSON.stringify(body),
      });
      const j = await res.json().catch(() => ({}));
      if (!res.ok) {
        throw new Error(j?.detail || j?.error || `HTTP ${res.status}`);
      }
      setResults(j.data?.results || []);
      setTotal(j.data?.total || 0);
      setFacets(j.data?.facets || { docTypeCode: {}, signed: { signed: 0, unsigned: 0 }, project: {} });
      setLatencyMs(j.data?.latencyMs);
      setSearchedMode(j.data?.mode);
    } catch (err) {
      pushToast({ title: 'Ricerca fallita', desc: err?.message?.slice(0, 200) || 'errore', tone: 'err' });
      setResults([]);
      setTotal(0);
    } finally {
      setSearching(false);
    }
  }, [q, filters, mode, user?.id, pushToast]);

  // First load: search senza filtri = tutti i documenti
  React.useEffect(() => { runSearch({}, ''); }, []); // eslint-disable-line

  const handleAdhocResult = (parsed) => {
    setQ(parsed.q || '');
    setFilters(parsed.filters || {});
    setParseReasoning(parsed.reasoning || null);
    setAdhocOpen(false);
    runSearch(parsed.filters || {}, parsed.q || '');
  };

  const toggleFilter = (key, value) => {
    setFilters(prev => {
      const next = { ...prev };
      if (next[key] === value) {
        delete next[key];
      } else {
        next[key] = value;
      }
      return next;
    });
  };

  const clearFilters = () => {
    setFilters({});
    setQ('');
    setParseReasoning(null);
    runSearch({}, '');
  };

  const activeFilterCount = Object.keys(filters).length;

  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <div className="eyebrow">Knowledge</div>
          <h1 className="page-title">Archivio storico</h1>
          <div className="page-sub">
            Ricerca full-text + semantica sui documenti indicizzati. {total > 0 ? `${total} documenti totali` : 'Carica documenti per iniziare a indicizzare l\'archivio.'}
          </div>
        </div>
        <div className="actions">
          <Btn variant="ghost" size="sm" onClick={reloadIndexStatus} title="Aggiorna stato indicizzazione">
            <Icon name="refresh" size={12}/>
          </Btn>
          <Btn variant="ai" size="sm" onClick={() => setAdhocOpen(true)}>
            <Icon name="sparkle" size={12}/> Indagine ad hoc
          </Btn>
        </div>
      </div>

      {/* FASE 14 — banner stato indicizzazione + bulk action */}
      {indexStatus && (
        <div className="card" style={{ marginBottom: 14, borderLeft: indexStatus.notIndexed > 0 ? '3px solid var(--warn)' : '3px solid var(--ok)' }}>
          <div className="card-body" style={{ padding: '10px 14px' }}>
            <div className="row" style={{ gap: 16, alignItems: 'center', flexWrap: 'wrap' }}>
              <div className="row" style={{ gap: 6 }}>
                <Icon name="package" size={13}/>
                <span style={{ fontSize: 12.5, fontWeight: 500 }}>Indicizzazione archivio</span>
              </div>
              <div style={{ display: 'flex', gap: 12, fontSize: 11.5, color: 'var(--text-2)', flexWrap: 'wrap' }}>
                <span><strong>{indexStatus.indexed}</strong>/{indexStatus.withFile} indicizzati</span>
                {indexStatus.notIndexed > 0 && (
                  <span style={{ color: 'var(--warn)' }}>
                    <Icon name="alert-triangle" size={10}/> {indexStatus.notIndexed} non ancora indicizzati
                  </span>
                )}
                {indexStatus.withError > 0 && (
                  <span style={{ color: 'var(--err)' }}>
                    <Icon name="x" size={10}/> {indexStatus.withError} con errore
                  </span>
                )}
                <span style={{ color: 'var(--text-3)' }}>· {indexStatus.total} record totali (incl. solo metadata)</span>
              </div>
              <span className="spacer"/>
              <div className="row" style={{ gap: 6 }}>
                <Btn variant="ghost" size="sm" disabled={bulkRunning} onClick={() => runBulkReindex({ force: false })}>
                  <Icon name="refresh" size={11}/> Indicizza mancanti
                </Btn>
                <Btn variant="ghost" size="sm" disabled={bulkRunning} onClick={() => runBulkReindex({ force: true })}>
                  <Icon name="refresh" size={11}/> Re-indicizza tutto
                </Btn>
              </div>
            </div>
            {bulkResult && (
              <div style={{ marginTop: 8, padding: '8px 10px', background: 'var(--bg-2)', borderRadius: 6, fontSize: 11 }}>
                <div className="row" style={{ gap: 8, flexWrap: 'wrap' }}>
                  <Chip kind="info">batch: {bulkResult.selected}</Chip>
                  <Chip kind="ok">enqueued: {bulkResult.enqueued}</Chip>
                  {bulkResult.skipped > 0 && <Chip kind="">skip: {bulkResult.skipped}</Chip>}
                  {bulkResult.reasons?.no_file > 0 && <span style={{ color: 'var(--text-3)' }}>no_file={bulkResult.reasons.no_file}</span>}
                  {bulkResult.reasons?.already_indexed > 0 && <span style={{ color: 'var(--text-3)' }}>already_indexed={bulkResult.reasons.already_indexed}</span>}
                </div>
                {bulkJobs.length > 0 && (
                  <div style={{ marginTop: 6, display: 'flex', gap: 4, flexWrap: 'wrap' }}>
                    {bulkJobs.map((j) => {
                      const tone = j.state === 'completed' ? 'ok' : j.state === 'failed' ? 'err' : j.state === 'active' ? 'info' : '';
                      return <Chip key={j.jobId} kind={tone} dot title={`${j.docId} · ${j.state}`}>{j.state}</Chip>;
                    })}
                  </div>
                )}
              </div>
            )}
          </div>
        </div>
      )}

      {/* Search bar */}
      <div className="card" style={{ marginBottom: 14 }}>
        <div className="card-body tight">
          <div className="row" style={{ gap: 10, padding: '2px 4px' }}>
            <Icon name="search" size={14} />
            <input
              placeholder="Cerca per parole o concetti (es. 'nomina responsabile lavori', 'offerta vendor 100k')"
              value={q}
              onChange={(e) => setQ(e.target.value)}
              onKeyDown={(e) => { if (e.key === 'Enter') runSearch(); }}
              style={{ background: 'transparent', border: 'none', outline: 'none', flex: 1, fontSize: 14, padding: '10px 0' }}
            />
            <select value={mode} onChange={(e) => setMode(e.target.value)} style={{ background: 'transparent', border: '1px solid var(--line)', borderRadius: 4, fontSize: 11.5, padding: '4px 6px' }}>
              <option value="hybrid">Hybrid (testo + semantica)</option>
              <option value="keyword">Solo keyword</option>
              <option value="semantic">Solo semantica</option>
            </select>
            <Btn variant="primary" size="sm" onClick={() => runSearch()} disabled={searching}>
              {searching ? 'Cerco…' : <><Icon name="search" size={12}/> Cerca</>}
            </Btn>
          </div>
        </div>
      </div>

      {parseReasoning && (
        <div className="card" style={{ marginBottom: 14, borderLeft: '3px solid var(--accent)' }}>
          <div className="card-body" style={{ fontSize: 12.5 }}>
            <div className="row" style={{ gap: 6, marginBottom: 6 }}><Icon name="sparkle" size={12}/><strong>AI Copilot · interpretazione</strong></div>
            <p style={{ margin: 0, lineHeight: 1.6 }}>{parseReasoning}</p>
          </div>
        </div>
      )}

      <div className="grid" style={{ gridTemplateColumns: selected ? '240px 1fr 380px' : '240px 1fr', gap: 14 }}>
        {/* Sidebar filtri */}
        <div className="card">
          <div className="card-header">
            <div className="title">Filtri {activeFilterCount > 0 && <Chip>{activeFilterCount}</Chip>}</div>
            {activeFilterCount > 0 && (
              <div className="actions">
                <Btn variant="ghost" size="sm" onClick={clearFilters}>Pulisci</Btn>
              </div>
            )}
          </div>
          <div className="card-body" style={{ padding: '8px 10px' }}>
            <div style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--text-2)', marginBottom: 4 }}>Tipo documento</div>
            <div style={{ maxHeight: 220, overflow: 'auto' }}>
              {Object.entries(facets.docTypeCode || {})
                .sort((a, b) => b[1] - a[1])
                .slice(0, 30)
                .map(([code, count]) => {
                  const dt = docTypes.find(d => d.code === code);
                  const active = filters.docTypeCode === code || (Array.isArray(filters.docTypeCode) && filters.docTypeCode.includes(code));
                  return (
                    <div
                      key={code}
                      onClick={() => toggleFilter('docTypeCode', code)}
                      className={active ? 'is-selected' : ''}
                      style={{
                        cursor: 'pointer',
                        padding: '4px 6px',
                        borderRadius: 3,
                        fontSize: 11.5,
                        background: active ? 'color-mix(in oklch, var(--accent) 14%, var(--bg-1))' : 'transparent',
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'center',
                        marginBottom: 1,
                      }}
                      title={dt?.name || code}
                    >
                      <span className="mono" style={{ fontSize: 11 }}>{code}</span>
                      <span style={{ color: 'var(--text-3)', fontSize: 10.5 }}>{count}</span>
                    </div>
                  );
                })}
              {Object.keys(facets.docTypeCode || {}).length === 0 && (
                <div style={{ fontSize: 11, color: 'var(--text-3)', padding: '4px 6px' }}>Nessun tipo</div>
              )}
            </div>

            <div style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--text-2)', margin: '12px 0 4px' }}>Stato firma</div>
            <div className="row" style={{ gap: 4 }}>
              <button
                className={`btn sm ${filters.signed === true ? 'primary' : 'ghost'}`}
                onClick={() => toggleFilter('signed', true)}
                style={{ fontSize: 10.5 }}
              >
                Firmati ({facets.signed?.signed || 0})
              </button>
              <button
                className={`btn sm ${filters.signed === false ? 'primary' : 'ghost'}`}
                onClick={() => toggleFilter('signed', false)}
                style={{ fontSize: 10.5 }}
              >
                Non firmati ({facets.signed?.unsigned || 0})
              </button>
            </div>

            <div style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--text-2)', margin: '12px 0 4px' }}>File allegato</div>
            <div className="row" style={{ gap: 4 }}>
              <button
                className={`btn sm ${filters.hasFile === true ? 'primary' : 'ghost'}`}
                onClick={() => toggleFilter('hasFile', true)}
                style={{ fontSize: 10.5 }}
              >
                Solo con file
              </button>
            </div>

            <div style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--text-2)', margin: '12px 0 4px' }}>Range data</div>
            <input
              type="date"
              value={filters.fromDate || ''}
              onChange={(e) => setFilters(prev => ({ ...prev, fromDate: e.target.value || undefined }))}
              style={{ width: '100%', fontSize: 11, padding: 4 }}
              placeholder="Da"
            />
            <input
              type="date"
              value={filters.toDate || ''}
              onChange={(e) => setFilters(prev => ({ ...prev, toDate: e.target.value || undefined }))}
              style={{ width: '100%', fontSize: 11, padding: 4, marginTop: 4 }}
              placeholder="A"
            />

            <div style={{ marginTop: 12 }}>
              <Btn variant="primary" size="sm" onClick={() => runSearch()} style={{ width: '100%' }}>
                <Icon name="check" size={11}/> Applica filtri
              </Btn>
            </div>
          </div>
        </div>

        {/* Results list */}
        <div className="card">
          <div className="card-header">
            <div className="title">
              {searching ? 'Ricerca in corso…' : `${results.length} risultati su ${total}`}
              {searchedMode && <Chip>{searchedMode}</Chip>}
            </div>
            <div className="actions">
              {latencyMs != null && <span style={{ fontSize: 10.5, color: 'var(--text-3)' }}>{latencyMs}ms</span>}
            </div>
          </div>
          <div>
            {results.length === 0 && !searching ? (
              <EmptyState
                title="Nessun risultato"
                desc={total === 0
                  ? "L'archivio è vuoto o nessun documento è stato indicizzato. Carica documenti dai progetti per iniziare."
                  : "Modifica i filtri o usa 'Indagine ad hoc' per cercare con linguaggio naturale."}
              />
            ) : results.map((r) => (
              <div
                key={r.document.id}
                className="clickable"
                onClick={() => setSelected(r)}
                style={{
                  padding: '12px 14px',
                  borderBottom: '1px solid var(--line)',
                  background: selected?.document?.id === r.document.id ? 'color-mix(in oklch, var(--accent) 8%, var(--bg-1))' : 'transparent',
                }}
              >
                <div className="row" style={{ gap: 8, alignItems: 'flex-start' }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div className="row" style={{ gap: 6, alignItems: 'center', marginBottom: 4 }}>
                      <strong style={{ fontSize: 13 }}>{r.document.title}</strong>
                      <Chip>{r.document.type}</Chip>
                      {r.document.signatureStatus === 'signed' && <Chip kind="ok" dot>firmato</Chip>}
                      {r.document.fileVersion > 1 && <Chip>v{r.document.fileVersion}</Chip>}
                    </div>
                    {r.snippet && (
                      <div style={{ fontSize: 11.5, color: 'var(--text-2)', lineHeight: 1.5 }}>{r.snippet}</div>
                    )}
                    <div className="row" style={{ gap: 8, marginTop: 6, fontSize: 10.5, color: 'var(--text-3)' }}>
                      <span className="mono">{r.document.projectId || '—'}</span>
                      {r.document.uploadedAt && <span>{fmtDate(r.document.uploadedAt)}</span>}
                      {r.document.fileSize && <span>{(r.document.fileSize / 1024).toFixed(1)} KB</span>}
                      {r.document.indexedAt ? (
                        <span style={{ color: 'var(--ok)' }}>indicizzato</span>
                      ) : (
                        <span style={{ color: 'var(--warn)' }}>non indicizzato</span>
                      )}
                    </div>
                  </div>
                  <div style={{ textAlign: 'right' }}>
                    <Chip kind="ai">match {(r.scores.total * 100).toFixed(0)}%</Chip>
                    <div style={{ fontSize: 9.5, color: 'var(--text-3)', marginTop: 4, fontFamily: 'var(--font-mono)' }}>
                      kw {(r.scores.fts * 100).toFixed(0)} · sm {(r.scores.cosine * 100).toFixed(0)} · rec {(r.scores.recency * 100).toFixed(0)}
                    </div>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Detail */}
        {selected && (
          <div className="card">
            <div className="card-header">
              <div className="title">{selected.document.title}</div>
              <div className="actions"><button className="btn ghost icon" onClick={() => setSelected(null)}><Icon name="x"/></button></div>
            </div>
            <div className="card-body">
              <div className="row" style={{ gap: 6, flexWrap: 'wrap' }}>
                <Chip>{selected.document.type}</Chip>
                {selected.document.fileVersion > 1 && <Chip>v{selected.document.fileVersion}</Chip>}
                {selected.document.signatureStatus === 'signed' && <Chip kind="ok" dot>firmato da {selected.document.signedBy}</Chip>}
              </div>
              <div style={{ fontSize: 11.5, color: 'var(--text-2)', marginTop: 8 }}>
                <div><strong>Progetto:</strong> <code>{selected.document.projectId}</code></div>
                {selected.document.uploadedAt && <div><strong>Caricato:</strong> {new Date(selected.document.uploadedAt).toLocaleString('it-IT')}</div>}
                {selected.document.signedAt && <div><strong>Firmato:</strong> {new Date(selected.document.signedAt).toLocaleString('it-IT')}</div>}
                {selected.document.fileSize && <div><strong>Size:</strong> {(selected.document.fileSize / 1024).toFixed(1)} KB</div>}
                {selected.document.originalFilename && <div><strong>File:</strong> <code>{selected.document.originalFilename}</code></div>}
              </div>
              {selected.snippet && (
                <div style={{ marginTop: 14 }}>
                  <div className="eyebrow">Snippet</div>
                  <p style={{ fontSize: 12, lineHeight: 1.6, marginTop: 4, padding: 8, background: 'var(--bg-2)', borderRadius: 4 }}>{selected.snippet}</p>
                </div>
              )}
              <div style={{ marginTop: 14 }}>
                <div className="eyebrow">Score breakdown</div>
                <table className="tbl dense" style={{ marginTop: 4 }}>
                  <tbody>
                    <tr><td style={{ fontSize: 11 }}>Keyword (FTS)</td><td className="num">{(selected.scores.fts * 100).toFixed(1)}%</td></tr>
                    <tr><td style={{ fontSize: 11 }}>Semantic (cosine)</td><td className="num">{(selected.scores.cosine * 100).toFixed(1)}%</td></tr>
                    <tr><td style={{ fontSize: 11 }}>Recency</td><td className="num">{(selected.scores.recency * 100).toFixed(1)}%</td></tr>
                    <tr style={{ fontWeight: 600 }}><td style={{ fontSize: 11 }}>Totale</td><td className="num">{(selected.scores.total * 100).toFixed(1)}%</td></tr>
                  </tbody>
                </table>
              </div>
              {selected.document.hasFile && (
                <div className="row" style={{ marginTop: 14, gap: 6 }}>
                  <a
                    className="btn primary sm"
                    href={`/api/documents/${encodeURIComponent(selected.document.id)}/download`}
                    download
                  >
                    <Icon name="download" size={12}/> Scarica file
                  </a>
                </div>
              )}
            </div>
          </div>
        )}
      </div>

      {adhocOpen && <IndagineAdHocModal onClose={() => setAdhocOpen(false)} onResult={handleAdhocResult} />}
    </div>
  );
}

/**
 * FASE 2c.7 (Sprint 5 cliente): modal "Indagine ad hoc".
 * L'utente scrive una richiesta NL → AI traduce in q + filters strutturati.
 */
function IndagineAdHocModal({ onClose, onResult }) {
  const { user, pushToast } = useStore();
  const [nlQuery, setNlQuery] = React.useState('');
  const [parsing, setParsing] = React.useState(false);

  async function handleParse() {
    if (!nlQuery.trim()) {
      pushToast({ title: 'Scrivi una richiesta', tone: 'warn' });
      return;
    }
    setParsing(true);
    try {
      const res = await fetch('/api/search/parse-query', {
        method: 'POST',
        headers: { 'content-type': 'application/json', 'X-Actor-Persona-Id': user?.id || '' },
        body: JSON.stringify({ nlQuery: nlQuery.trim() }),
      });
      const j = await res.json().catch(() => ({}));
      if (!res.ok) {
        const msg = j?.detail || j?.error || `HTTP ${res.status}`;
        throw new Error(msg);
      }
      onResult(j.data);
    } catch (err) {
      pushToast({ title: 'Indagine non riuscita', desc: err?.message?.slice(0, 200) || 'errore', tone: 'err' });
    } finally {
      setParsing(false);
    }
  }

  return (
    <Modal
      open
      onClose={onClose}
      title="Indagine ad hoc · linguaggio naturale"
      size="md"
      footer={
        <>
          <Btn variant="ghost" size="sm" onClick={onClose}>Annulla</Btn>
          <Btn variant="ai" size="sm" onClick={handleParse} disabled={parsing || !nlQuery.trim()}>
            {parsing ? 'Interpreto…' : <><Icon name="sparkle" size={12}/> Esegui indagine</>}
          </Btn>
        </>
      }
    >
      <div className="col" style={{ gap: 14 }}>
        <div style={{ fontSize: 12, color: 'var(--text-2)' }}>
          Descrivi cosa cerchi in linguaggio naturale. AI traduce la richiesta in filtri sui documenti dell'archivio (tipo documento, range date, stato firma, progetto).
        </div>
        <div className="field">
          <label>Richiesta</label>
          <textarea
            rows={4}
            value={nlQuery}
            onChange={(e) => setNlQuery(e.target.value)}
            placeholder="Es: 'Tutte le offerte vendor degli ultimi 6 mesi non firmate' · 'Nomine RL del progetto P-2026-007 firmate' · 'Specifiche tecniche con riferimenti SAP'"
            style={{ width: '100%', resize: 'vertical' }}
          />
        </div>
        <div style={{ fontSize: 10.5, color: 'var(--text-3)', padding: 8, background: 'var(--bg-2)', borderRadius: 4 }}>
          <Icon name="info" size={10}/> AI interpreta la richiesta e applica filtri strutturati. Puoi modificare i filtri risultanti dopo l'esecuzione.
        </div>
      </div>
    </Modal>
  );
}

Object.assign(window, { Archive });
