// ============================================================
// project-health-badge.jsx
// ============================================================
// FASE 6 Project Cockpit (sessione 106) — Badge Project Health Score composito
// nel header di ProjectDetail. Cliccabile → apre modal drill-down con
// breakdown per dimensione, weightsUsed (rinormalizzati su missing signals)
// e razionale AI (se la policy è stata suggested da AI).
//
// Si registra anche `window.openProjectHealthBadge` (no-op se non utilizzato
// da altri componenti) per coerenza col pattern modali-globali.

(() => {
  const { useState, useEffect, useMemo } = React;

  const DIMENSION_LABELS = {
    compliance: 'Compliance',
    schedule: 'Schedule (SPI)',
    cost: 'Cost (CPI)',
    governance: 'Governance',
    risks: 'Risks',
  };

  const DIMENSION_DESC = {
    compliance: '% checklist documentale completata sul progetto.',
    schedule: 'SPI = EV / PV. >1.0 in anticipo, <1.0 in ritardo. Cap 100 a SPI=1.0.',
    cost: 'CPI = EV / AC. >1.0 sotto budget, <1.0 over. Cap 100 a CPI=1.0.',
    governance: '100 − (step bloccati × 10) − (SLA breach × 5).',
    risks: '100 − Σ anomalie × peso severità (low=2, medium=5, high=10, critical=25).',
  };

  const MISSING_REASON_LABEL = {
    no_applicable_checklist_rules: 'Nessuna regola checklist applicabile',
    no_baseline_evm: 'Nessun baseline EVM caricato',
    no_active_workflows: 'Nessun workflow attivo',
  };

  function overallToTone(overall) {
    if (overall === 'ok') return { color: '#22c55e', label: 'In salute', bg: 'rgba(34,197,94,0.12)' };
    if (overall === 'warn') return { color: '#f59e0b', label: 'Attenzione', bg: 'rgba(245,158,11,0.12)' };
    return { color: '#ef4444', label: 'Critico', bg: 'rgba(239,68,68,0.12)' };
  }

  function subScoreTone(score) {
    if (score >= 80) return '#22c55e';
    if (score >= 60) return '#f59e0b';
    return '#ef4444';
  }

  function pct(n) {
    return Math.round(n * 100) + '%';
  }

  function ProjectHealthBadge({ projectId }) {
    const { user } = useStore();
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    const [modalOpen, setModalOpen] = useState(false);

    useEffect(() => {
      let cancelled = false;
      if (!projectId) return;
      setLoading(true);
      setError(null);
      fetch(`/api/projects/${encodeURIComponent(projectId)}/health-score`, {
        headers: { 'X-Actor-Persona-Id': user?.id || '' },
        credentials: 'same-origin',
      })
        .then((r) => r.json().then((j) => ({ ok: r.ok, j })))
        .then(({ ok, j }) => {
          if (cancelled) return;
          if (!ok) {
            setError(j?.error || 'fetch_failed');
            return;
          }
          setData(j?.data || null);
        })
        .catch((e) => !cancelled && setError(String(e?.message || e)))
        .finally(() => !cancelled && setLoading(false));
      return () => {
        cancelled = true;
      };
    }, [projectId, user?.id]);

    if (loading) {
      return (
        <div
          className="card"
          style={{ padding: '8px 12px', minWidth: 240, fontSize: 11.5, color: 'var(--text-2)' }}
        >
          Calcolo health score…
        </div>
      );
    }
    if (error || !data?.result) {
      return null;
    }

    const result = data.result;
    const tone = overallToTone(result.overall);

    return (
      <>
        <button
          onClick={() => setModalOpen(true)}
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: 12,
            background: tone.bg,
            border: `1px solid ${tone.color}40`,
            borderRadius: 8,
            padding: '8px 12px',
            cursor: 'pointer',
            color: 'var(--text-0)',
            fontFamily: 'inherit',
            textAlign: 'left',
          }}
          title="Vedi breakdown salute progetto"
          data-action="open-health-modal"
        >
          <div style={{ display: 'flex', flexDirection: 'column', minWidth: 50, alignItems: 'center' }}>
            <div style={{ fontSize: 22, fontWeight: 700, color: tone.color, lineHeight: 1 }}>
              {result.score}
            </div>
            <div style={{ fontSize: 9.5, color: 'var(--text-2)', marginTop: 2 }}>HEALTH</div>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            <div style={{ fontSize: 11, fontWeight: 600, color: tone.color }}>{tone.label}</div>
            <div style={{ display: 'flex', gap: 4 }}>
              {['compliance', 'schedule', 'cost', 'governance', 'risks'].map((d) => {
                const v = result.breakdown[d];
                if (v == null) {
                  return (
                    <span
                      key={d}
                      title={`${DIMENSION_LABELS[d]} — segnale assente`}
                      style={{
                        fontSize: 9.5,
                        padding: '2px 6px',
                        background: 'var(--bg-3)',
                        color: 'var(--text-3)',
                        borderRadius: 4,
                        fontWeight: 500,
                      }}
                    >
                      —
                    </span>
                  );
                }
                return (
                  <span
                    key={d}
                    title={`${DIMENSION_LABELS[d]}: ${Math.round(v)}`}
                    style={{
                      fontSize: 9.5,
                      padding: '2px 6px',
                      background: subScoreTone(v) + '22',
                      color: subScoreTone(v),
                      borderRadius: 4,
                      fontWeight: 600,
                    }}
                  >
                    {Math.round(v)}
                  </span>
                );
              })}
            </div>
          </div>
        </button>

        {modalOpen && <HealthScoreModal data={data} onClose={() => setModalOpen(false)} />}
      </>
    );
  }

  function HealthScoreModal({ data, onClose }) {
    const result = data.result;
    const signals = data.signals;
    const policy = data.policy;
    const tone = overallToTone(result.overall);

    return (
      <div
        onClick={onClose}
        style={{
          position: 'fixed',
          inset: 0,
          background: 'rgba(0,0,0,0.6)',
          zIndex: 1000,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          padding: 20,
        }}
      >
        <div
          onClick={(e) => e.stopPropagation()}
          style={{
            background: 'var(--bg-1)',
            border: '1px solid var(--line)',
            borderRadius: 12,
            maxWidth: 720,
            width: '100%',
            maxHeight: '90vh',
            overflowY: 'auto',
            padding: 24,
          }}
        >
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 16 }}>
            <div>
              <div style={{ fontSize: 10, color: 'var(--text-2)', fontWeight: 600, letterSpacing: '.05em' }}>
                HEALTH SCORE — {data.project?.code}
              </div>
              <h2 style={{ marginTop: 6, fontSize: 22 }}>{data.project?.name}</h2>
            </div>
            <button
              onClick={onClose}
              style={{ background: 'none', border: 'none', color: 'var(--text-2)', fontSize: 22, cursor: 'pointer' }}
            >
              ×
            </button>
          </div>

          <div
            style={{
              display: 'flex',
              gap: 24,
              alignItems: 'center',
              padding: 16,
              background: tone.bg,
              borderRadius: 8,
              marginBottom: 20,
            }}
          >
            <div style={{ fontSize: 48, fontWeight: 700, color: tone.color, lineHeight: 1 }}>{result.score}</div>
            <div>
              <div style={{ fontSize: 14, fontWeight: 600, color: tone.color }}>{tone.label}</div>
              <div style={{ fontSize: 11, color: 'var(--text-2)', marginTop: 4 }}>
                Soglie: ok ≥{policy.thresholds.ok_min} · warn ≥{policy.thresholds.warn_min}
              </div>
            </div>
          </div>

          <div style={{ marginBottom: 16 }}>
            <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 8 }}>Breakdown per dimensione</div>
            <table style={{ width: '100%', fontSize: 11, borderCollapse: 'collapse' }}>
              <thead>
                <tr style={{ borderBottom: '1px solid var(--line)' }}>
                  <th style={{ textAlign: 'left', padding: 6, color: 'var(--text-2)', fontWeight: 500 }}>Dimensione</th>
                  <th style={{ textAlign: 'right', padding: 6, color: 'var(--text-2)', fontWeight: 500 }}>Sub-score</th>
                  <th style={{ textAlign: 'right', padding: 6, color: 'var(--text-2)', fontWeight: 500 }}>Peso config</th>
                  <th style={{ textAlign: 'right', padding: 6, color: 'var(--text-2)', fontWeight: 500 }}>Peso usato</th>
                  <th style={{ textAlign: 'left', padding: 6, color: 'var(--text-2)', fontWeight: 500 }}>Formula</th>
                </tr>
              </thead>
              <tbody>
                {['compliance', 'schedule', 'cost', 'governance', 'risks'].map((d) => {
                  const v = result.breakdown[d];
                  const w = policy.weights[d];
                  const wu = result.weightsUsed[d];
                  const missing = v == null;
                  return (
                    <tr key={d} style={{ borderBottom: '1px solid var(--line)' }}>
                      <td style={{ padding: 6, fontWeight: missing ? 400 : 500 }}>
                        {DIMENSION_LABELS[d]}
                        {missing && (
                          <span style={{ fontSize: 10, color: 'var(--text-3)', marginLeft: 6 }}>(escluso)</span>
                        )}
                      </td>
                      <td
                        style={{
                          padding: 6,
                          textAlign: 'right',
                          fontFamily: 'JetBrains Mono, monospace',
                          color: missing ? 'var(--text-3)' : subScoreTone(v),
                          fontWeight: missing ? 400 : 600,
                        }}
                      >
                        {missing ? '—' : Math.round(v)}
                      </td>
                      <td
                        style={{
                          padding: 6,
                          textAlign: 'right',
                          fontFamily: 'JetBrains Mono, monospace',
                          color: 'var(--text-2)',
                        }}
                      >
                        {pct(w)}
                      </td>
                      <td
                        style={{
                          padding: 6,
                          textAlign: 'right',
                          fontFamily: 'JetBrains Mono, monospace',
                          color: missing ? 'var(--text-3)' : 'var(--text-0)',
                        }}
                      >
                        {wu != null ? pct(wu) : '—'}
                      </td>
                      <td style={{ padding: 6, color: 'var(--text-2)', fontSize: 10.5 }}>{DIMENSION_DESC[d]}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>

          {result.missingSignals.length > 0 && (
            <div
              style={{
                padding: 12,
                background: 'var(--bg-2)',
                border: '1px solid var(--line)',
                borderRadius: 8,
                marginBottom: 16,
              }}
            >
              <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 8 }}>
                Segnali mancanti ({result.missingSignals.length})
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {result.missingSignals.map((m) => (
                  <div key={m.dimension} style={{ fontSize: 11, color: 'var(--text-2)' }}>
                    <strong style={{ color: 'var(--text-0)' }}>{DIMENSION_LABELS[m.dimension]}</strong>:{' '}
                    {MISSING_REASON_LABEL[m.reason] || m.reason}
                  </div>
                ))}
              </div>
              <div style={{ fontSize: 10.5, color: 'var(--text-3)', marginTop: 8 }}>
                I pesi delle dimensioni disponibili sono stati rinormalizzati sul totale residuo.
              </div>
            </div>
          )}

          {signals && (
            <div style={{ marginBottom: 16 }}>
              <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 8 }}>Segnali grezzi</div>
              <div
                style={{
                  display: 'grid',
                  gridTemplateColumns: 'repeat(3, 1fr)',
                  gap: 8,
                  fontSize: 10.5,
                  fontFamily: 'JetBrains Mono, monospace',
                }}
              >
                <SignalBox label="Checklist" value={signals.checklistCompletion != null ? pct(signals.checklistCompletion) : '—'} />
                <SignalBox label="CPI" value={signals.evmCpi != null ? signals.evmCpi.toFixed(2) : '—'} />
                <SignalBox label="SPI" value={signals.evmSpi != null ? signals.evmSpi.toFixed(2) : '—'} />
                <SignalBox label="Step bloccati" value={signals.blockedWorkflowSteps} />
                <SignalBox label="SLA breach 90gg" value={signals.slaBreaches} />
                <SignalBox
                  label="Anomalie aperte"
                  value={
                    (signals.anomaliesByLevel.low || 0) +
                    (signals.anomaliesByLevel.medium || 0) +
                    (signals.anomaliesByLevel.high || 0) +
                    (signals.anomaliesByLevel.critical || 0)
                  }
                  tooltip={`L${signals.anomaliesByLevel.low || 0} M${signals.anomaliesByLevel.medium || 0} H${signals.anomaliesByLevel.high || 0} C${signals.anomaliesByLevel.critical || 0}`}
                />
              </div>
            </div>
          )}

          {policy.aiRationale && (
            <div
              style={{
                padding: 12,
                background: 'rgba(99,102,241,0.08)',
                border: '1px solid rgba(99,102,241,0.3)',
                borderRadius: 8,
              }}
            >
              <div style={{ fontSize: 11, fontWeight: 600, marginBottom: 6, color: 'rgb(129,140,248)' }}>
                ✨ Razionale AI sulla policy pesi
              </div>
              <div style={{ fontSize: 11, color: 'var(--text-1)', lineHeight: 1.5 }}>{policy.aiRationale}</div>
              {policy.aiSuggestedAt && (
                <div style={{ fontSize: 10, color: 'var(--text-3)', marginTop: 6 }}>
                  Suggerito il {new Date(policy.aiSuggestedAt).toLocaleString('it-IT')} via {policy.aiProvider}/{policy.aiModel}
                </div>
              )}
            </div>
          )}
        </div>
      </div>
    );
  }

  function SignalBox({ label, value, tooltip }) {
    return (
      <div
        title={tooltip}
        style={{
          padding: 8,
          background: 'var(--bg-2)',
          borderRadius: 6,
          border: '1px solid var(--line)',
        }}
      >
        <div style={{ fontSize: 9, color: 'var(--text-2)', marginBottom: 4, letterSpacing: '.04em' }}>
          {label.toUpperCase()}
        </div>
        <div style={{ fontSize: 14, color: 'var(--text-0)', fontWeight: 600 }}>{value}</div>
      </div>
    );
  }

  window.ProjectHealthBadge = ProjectHealthBadge;
  window.HealthScoreModal = HealthScoreModal;
})();
