// ============================================================
// ai-insight.jsx — Pannello "Insight AI" riusabile (REALE)
// ============================================================
//
// Cluster Realizzazione · Fase A. Sostituisce gli insight finti
// (regole locali / testo hardcoded) con una vera chiamata all'LLM
// tramite window.aiAsk → POST /api/ai/invoke (provenance ledger +
// audit-safe, multi-provider da ai_credentials).
//
// Props:
//   system     : system prompt (string) — istruzioni di ruolo per l'agente
//   prompt     : user prompt (string) — contesto dati su cui ragionare
//   autoRun    : bool — se true genera automaticamente al mount/cambio runKey
//   runKey     : valore che, cambiando, ri-triggera l'autoRun (es. id selezionato)
//   idleLabel  : label del bottone di generazione (default "Genera insight AI")
//   emptyHint  : testo mostrato in stato idle sotto il bottone (opzionale)
//   compact    : bool — riduce padding/spaziature per card piccole
//
// Stati: idle → loading → done | error. Mostra provenance (source/provider/
// model/latencyMs) + fallback flag + bottone "Rigenera".

// keyframes per il pulse "sta ragionando" — iniettato una sola volta.
(function ensureAiInsightStyles() {
  if (typeof document === 'undefined') return;
  if (document.getElementById('ai-insight-styles')) return;
  const style = document.createElement('style');
  style.id = 'ai-insight-styles';
  style.textContent =
    '@keyframes ai-pulse{0%,100%{opacity:.35}50%{opacity:1}}' +
    '.ai-insight-thinking{animation:ai-pulse 1.1s ease-in-out infinite}' +
    '.ai-insight-dot{display:inline-block;width:5px;height:5px;border-radius:50%;background:var(--ai,#7c5cff);margin-right:3px;animation:ai-pulse 1.1s ease-in-out infinite}' +
    '.ai-insight-dot:nth-child(2){animation-delay:.18s}.ai-insight-dot:nth-child(3){animation-delay:.36s}';
  document.head.appendChild(style);
})();

// Render markdown-lite: grassetto **x**, righe "- "/"• "/"* " come lista.
// Niente parser pesante: robustezza > completezza. whiteSpace pre-wrap sui paragrafi.
function renderAiInline(text) {
  const parts = String(text).split(/(\*\*[^*]+\*\*)/g);
  return parts.map((p, i) =>
    p.startsWith('**') && p.endsWith('**')
      ? <strong key={i}>{p.slice(2, -2)}</strong>
      : <React.Fragment key={i}>{p}</React.Fragment>
  );
}

function AiInsightBody({ text }) {
  // Renderer ricco condiviso (s127): delega ad AiMarkdown (heading, tabelle reali,
  // liste, codice, grafici ```chart). Fallback al parser minimale se non caricato.
  if (window.AiMarkdown) return <window.AiMarkdown text={text || ''} />;
  const lines = String(text || '').split('\n');
  const blocks = [];
  let list = null;
  const flush = () => { if (list) { blocks.push(list); list = null; } };
  lines.forEach((raw, idx) => {
    const line = raw.trimEnd();
    const m = line.match(/^\s*[-•*]\s+(.*)$/);
    if (m) {
      if (!list) list = { type: 'ul', items: [] };
      list.items.push(m[1]);
    } else if (line.trim() === '') {
      flush();
    } else {
      flush();
      blocks.push({ type: 'p', text: line });
    }
  });
  flush();
  return (
    <div style={{ fontSize: 12.5, lineHeight: 1.6, color: 'var(--text-1)' }}>
      {blocks.map((b, i) =>
        b.type === 'ul'
          ? <ul key={i} style={{ margin: '6px 0', paddingLeft: 18 }}>
              {b.items.map((it, j) => <li key={j}>{renderAiInline(it)}</li>)}
            </ul>
          : <p key={i} style={{ margin: '0 0 6px' }}>{renderAiInline(b.text)}</p>
      )}
    </div>
  );
}

function aiSourceLabel(r) {
  if (!r) return '';
  if (r.source === 'simulated' || r.fallback) {
    return r.fallback ? `${r.provider || 'AI'} · fallback simulato` : 'modalità simulata';
  }
  const prov = r.provider || r.source || 'AI';
  const model = r.model ? ` · ${r.model}` : '';
  const lat = Number.isFinite(r.latencyMs) ? ` · ${(r.latencyMs / 1000).toFixed(1)}s` : '';
  return `${prov}${model}${lat}`;
}

function AiInsightPanel({ system, prompt, autoRun = false, runKey, idleLabel = 'Genera insight AI', emptyHint, compact = false }) {
  const [phase, setPhase] = React.useState('idle'); // idle | loading | done | error
  const [res, setRes] = React.useState(null);
  const [err, setErr] = React.useState(null);
  // Ref per evitare stale closure mantenendo run() stabile.
  const argsRef = React.useRef({ system, prompt });
  argsRef.current = { system, prompt };
  // Guardia contro race: se runKey cambia mentre una richiesta è in volo,
  // ignora la risposta vecchia.
  const reqIdRef = React.useRef(0);

  const run = React.useCallback(async () => {
    const myReq = ++reqIdRef.current;
    setPhase('loading'); setErr(null);
    try {
      const { system, prompt } = argsRef.current;
      const r = await window.aiAsk({ system, messages: [{ role: 'user', content: prompt }] });
      if (myReq !== reqIdRef.current) return; // superata da una richiesta più recente
      setRes(r); setPhase('done');
    } catch (e) {
      if (myReq !== reqIdRef.current) return;
      setErr(String(e?.message || e)); setPhase('error');
    }
  }, []);

  React.useEffect(() => {
    if (autoRun) {
      run();
    } else {
      reqIdRef.current++; // invalida eventuali richieste in volo
      setPhase('idle'); setRes(null); setErr(null);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [runKey, autoRun]);

  const pad = compact ? 0 : 2;

  if (phase === 'idle') {
    return (
      <div style={{ marginTop: pad }}>
        <Btn variant="ai" size="sm" onClick={run}><Icon name="sparkle" size={12} /> {idleLabel}</Btn>
        {emptyHint && <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 6 }}>{emptyHint}</div>}
      </div>
    );
  }

  if (phase === 'loading') {
    return (
      <div className="ai-insight-thinking" style={{ marginTop: pad, display: 'flex', alignItems: 'center', gap: 8, fontSize: 12, color: 'var(--text-2)' }}>
        <Icon name="sparkle" size={13} />
        <span>L'agente sta analizzando<span className="ai-insight-dot" /><span className="ai-insight-dot" /><span className="ai-insight-dot" /></span>
      </div>
    );
  }

  if (phase === 'error') {
    return (
      <div style={{ marginTop: pad }}>
        <div style={{ padding: '8px 10px', border: '1px solid var(--err)', borderRadius: 4, background: 'rgba(192,57,43,0.08)', color: 'var(--err)', fontSize: 11.5, lineHeight: 1.5 }}>
          <strong>Insight non disponibile.</strong> {err}
        </div>
        <Btn variant="ghost" size="sm" onClick={run} style={{ marginTop: 6 }}><Icon name="refresh" size={11} /> Riprova</Btn>
      </div>
    );
  }

  // done
  return (
    <div style={{ marginTop: pad }}>
      <AiInsightBody text={res?.text} />
      <div className="row" style={{ alignItems: 'center', gap: 8, marginTop: 8 }}>
        <span style={{ fontSize: 10, color: 'var(--text-3)', display: 'inline-flex', alignItems: 'center', gap: 4 }}>
          <Icon name="sparkle" size={9} /> {aiSourceLabel(res)}
        </span>
        <span className="spacer" />
        <Btn variant="ghost" size="sm" onClick={run}><Icon name="refresh" size={11} /> Rigenera</Btn>
      </div>
    </div>
  );
}

Object.assign(window, { AiInsightPanel, AiInsightBody, aiSourceLabel });
