import { useState, useEffect, useRef, useCallback } from 'react';
import { req, getToken, saveToken, ENDPOINTS } from '../api';
import { Card, CardHeader, Callout, FormGroup, ResponseBox } from '../components/ui';

const { AUTH, INTEL } = ENDPOINTS;

// ── Trust Gauge ───────────────────────────────────────────────────────────────
const TRUST_ARC = 204;
function TrustGauge({ score, label, color }) {
  const offset = TRUST_ARC - (score / 100) * TRUST_ARC;
  return (
    <div style={{ textAlign: 'center' }}>
      <svg width="160" height="100" viewBox="-5 -5 170 110" style={{ overflow: 'visible' }}>
        <path d="M 10 80 A 65 65 0 0 1 140 80" stroke="#e2e8f0" strokeWidth="16" fill="none" />
        <path
          d="M 10 80 A 65 65 0 0 1 140 80"
          stroke={color || '#16a34a'}
          strokeWidth="16"
          fill="none"
          strokeDasharray={TRUST_ARC}
          strokeDashoffset={offset}
          strokeLinecap="round"
          style={{ transition: 'stroke-dashoffset .6s, stroke .6s' }}
        />
        <text x="75" y="77" textAnchor="middle" fontSize="28" fontWeight="800" fill={color || '#16a34a'}>
          {Math.round(score)}
        </text>
        <text x="75" y="94" textAnchor="middle" fontSize="10" fill="#94a3b8">/ 100</text>
      </svg>
      <div className="trust-label" style={{ color: color || 'var(--muted)' }}>
        {(label || 'loading').toUpperCase()}
      </div>
    </div>
  );
}

// ── Behavior bar ──────────────────────────────────────────────────────────────
function BehaviorBar({ label, value }) {
  const color = value > 0.7 ? '#16a34a' : value > 0.4 ? '#d97706' : '#dc2626';
  return (
    <div className="behavior-bar-group">
      <div className="behavior-bar-header">
        <span>{label}</span>
        <span style={{ fontWeight: 700, color }}>{value.toFixed(2)}</span>
      </div>
      <div className="behavior-bar-track">
        <div className="behavior-bar-fill" style={{ width: `${value * 100}%`, background: color }} />
      </div>
    </div>
  );
}

// ── Travel result renderer ────────────────────────────────────────────────────
function TravelResult({ data }) {
  if (!data) return null;
  const CMAP = { impossible:'#dc2626', suspicious:'#f97316', plausible:'#16a34a', same_area:'#16a34a', coords_unknown:'#94a3b8' };
  const IMAP = { impossible:'🚨', suspicious:'⚠️', plausible:'✅', same_area:'✅', coords_unknown:'❓' };
  const col  = CMAP[data.verdict] || '#94a3b8';
  const icon = IMAP[data.verdict] || '❓';
  return (
    <div style={{ background: `${col}18`, border: `1px solid ${col}`, borderRadius: 8, padding: 12, marginTop: 10 }}>
      <div style={{ fontWeight: 700, fontSize: 15, color: col, marginBottom: 6 }}>
        {icon} {(data.verdict || '').toUpperCase().replace('_', ' ')}
      </div>
      <div className="text-sm">{data.message}</div>
      <div className="grid-3 mt-2" style={{ gap: 6 }}>
        {[
          { v: data.distance_km || 0,                  l: 'Distance', u: 'km' },
          { v: Math.round(data.speed_kmh || 0),        l: 'Speed',    u: 'km/h' },
          { v: Math.round(data.time_gap_minutes || 0), l: 'Gap',      u: 'min' },
        ].map(s => (
          <div key={s.l}>
            <div style={{ fontWeight: 700 }}>{s.v} {s.u}</div>
            <div className="text-xs text-muted">{s.l}</div>
          </div>
        ))}
      </div>
      {data.trust_delta < 0 && (
        <div className="text-sm text-warn mt-2">⚠ Trust impact: {data.trust_delta} pts</div>
      )}
    </div>
  );
}

// ── AI Anomaly result ─────────────────────────────────────────────────────────
function AnomalyResult({ data }) {
  if (!data) return null;
  return (
    <div style={{ background: `${data.color}18`, border: `1px solid ${data.color}`, borderRadius: 8, padding: 12, marginTop: 10 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
        <div style={{ fontWeight: 800, fontSize: 22, color: data.color }}>{data.anomaly_score.toFixed(1)} / 100</div>
        <div style={{ fontSize: 11, fontWeight: 700, background: data.color, color: '#fff', padding: '2px 10px', borderRadius: 4 }}>
          {data.classification}
        </div>
      </div>
      <div className="text-xs text-muted mb-2">
        Confidence: {(data.confidence * 100).toFixed(0)}% · Statistical Isolation Forest
      </div>
      {Object.entries(data.per_feature || {}).map(([fn, fs]) => {
        const fc = fs > 60 ? '#dc2626' : fs > 30 ? '#d97706' : '#16a34a';
        return (
          <div key={fn} style={{ marginBottom: 6 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11 }}>
              <span>{fn}</span><span style={{ color: fc }}>{fs.toFixed(1)}</span>
            </div>
            <div style={{ height: 5, background: '#e2e8f0', borderRadius: 3, overflow: 'hidden' }}>
              <div style={{ height: '100%', width: `${fs}%`, background: fc, borderRadius: 3 }} />
            </div>
          </div>
        );
      })}
    </div>
  );
}

export default function IntelTab({ onTokenSave }) {
  // Login status
  const [loginStatus, setLoginStatus] = useState('');
  // Trust
  const [trust,        setTrust]       = useState({ score: 0, label: 'loading', color: '#94a3b8' });
  const [trustHistory, setTrustHist]   = useState([]);
  const [trustResp,    setTrustResp]   = useState(null);
  // Behavior
  const [collecting,   setCollecting]  = useState(false);
  const [bhScores,     setBhScores]    = useState({ te: 0.5, ml: 0.6, sv: 0.5 });
  const [collectStatus,setCollStatus]  = useState('');
  const [behaviorResp, setBehavResp]   = useState(null);
  // Travel
  const [cities,       setCities]      = useState([]);
  const [travelFrom,   setTravelFrom]  = useState('New York');
  const [travelTo,     setTravelTo]    = useState('Moscow');
  const [travelHours,  setTravelHours] = useState('2');
  const [travelResult, setTravelResult]= useState(null);
  // AI Anomaly
  const [aiTyping,  setAiTyping]  = useState('0.70');
  const [aiMouse,   setAiMouse]   = useState('0.62');
  const [aiScroll,  setAiScroll]  = useState('0.48');
  const [aiHour,    setAiHour]    = useState('0.55');
  const [aiFailed,  setAiFailed]  = useState('0.00');
  const [anomResult, setAnomResult]= useState(null);
  // Challenge
  const [showChallenge,   setShowChallenge]   = useState(false);
  const [challengeQ,      setChallengeQ]      = useState('');
  const [challengeAnswer, setChallengeAnswer] = useState('');
  const [challengeMsg,    setChallengeMsg]    = useState('');
  const [challengeId,     setChallengeId]     = useState(null);
  const [challengeResp,   setChallengeResp]   = useState(null);
  // Explain
  const [expLoc,   setExpLoc]   = useState('85');
  const [expDev,   setExpDev]   = useState('15');
  const [expTime,  setExpTime]  = useState('10');
  const [expVel,   setExpVel]   = useState('5');
  const [expBeh,   setExpBeh]   = useState('20');
  const [expLevel, setExpLevel] = useState('2');
  const [explainResult, setExplainResult] = useState(null);
  // Session audit
  const [sessionResp, setSessionResp] = useState(null);
  // Loading
  const [loading, setLoading] = useState({});
  const setLoad = (k, v) => setLoading(p => ({ ...p, [k]: v }));

  // ── Behavior refs ─────────────────────────────────────────────────────────
  const bhKeyTimes  = useRef([]);
  const bhMousePts  = useRef([]);
  const bhScrollDs  = useRef([]);
  const bhLastKey   = useRef(0);
  const bhLastMouse = useRef(0);

  const onKeyDown = useCallback(e => {
    const now = performance.now();
    if (bhLastKey.current > 0) bhKeyTimes.current.push(now - bhLastKey.current);
    bhLastKey.current = now;
  }, []);
  const onMouseMove = useCallback(e => {
    const now = performance.now();
    if (now - bhLastMouse.current < 50) return;
    bhLastMouse.current = now;
    bhMousePts.current.push([e.clientX, e.clientY]);
  }, []);
  const onScroll = useCallback(e => {
    const d = e.target?.scrollTop != null ? Math.abs(e.target.scrollTop) : window.scrollY;
    bhScrollDs.current.push(d);
  }, []);

  const computeScores = useCallback(() => {
    // Typing entropy (coefficient of variation)
    let te = 0.5;
    const kt = bhKeyTimes.current;
    if (kt.length >= 3) {
      const mean = kt.reduce((a, b) => a + b, 0) / kt.length;
      const std  = Math.sqrt(kt.reduce((s, v) => s + (v - mean) ** 2, 0) / kt.length);
      const cv   = std / (mean + 1e-6);
      te = cv < 0.05 ? 0.10 : cv < 0.20 ? 0.30 + cv * 1.5 : cv < 0.90 ? 0.50 + (cv - 0.20) * 0.7 : Math.max(0.10, 1.0 - (cv - 0.90) * 0.8);
      te = Math.max(0, Math.min(1, te));
    }
    // Mouse linearity
    let ml = 0.6;
    const mp = bhMousePts.current;
    if (mp.length >= 3) {
      let totalD = 0;
      for (let i = 1; i < mp.length; i++) {
        const dx = mp[i][0] - mp[i-1][0], dy = mp[i][1] - mp[i-1][1];
        totalD += Math.sqrt(dx * dx + dy * dy);
      }
      const dxA = mp[mp.length-1][0] - mp[0][0], dyA = mp[mp.length-1][1] - mp[0][1];
      const straightD = Math.sqrt(dxA * dxA + dyA * dyA);
      ml = Math.max(0, Math.min(1, 1.0 - Math.abs((totalD > 0 ? straightD / totalD : 0) - 0.6) * 1.5));
    }
    // Scroll variance
    let sv = 0.5;
    const sd = bhScrollDs.current;
    if (sd.length >= 2) {
      const sm = sd.reduce((a, b) => a + b, 0) / sd.length;
      const ss = Math.sqrt(sd.reduce((s, v) => s + (v - sm) ** 2, 0) / sd.length);
      sv = Math.min(1, ss / 200);
    }
    return { te, ml, sv, lr: Math.max(0, 1.0 - (0.40 * te + 0.35 * ml + 0.25 * sv)) };
  }, []);

  const startCollecting = () => {
    bhKeyTimes.current = []; bhMousePts.current = []; bhScrollDs.current = [];
    bhLastKey.current = 0; bhLastMouse.current = 0;
    document.addEventListener('keydown',   onKeyDown);
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('scroll',    onScroll, true);
    setCollecting(true);
    setCollStatus('Collecting… (type, move mouse, scroll)');
    setBhScores({ te: 0.5, ml: 0.6, sv: 0.5 });
  };
  const stopCollecting = () => {
    document.removeEventListener('keydown',   onKeyDown);
    document.removeEventListener('mousemove', onMouseMove);
    document.removeEventListener('scroll',    onScroll, true);
    const s = computeScores();
    setBhScores(s);
    setCollecting(false);
    setCollStatus(`Done — Keys:${bhKeyTimes.current.length}  Mouse:${bhMousePts.current.length}  Scrolls:${bhScrollDs.current.length}`);
  };
  useEffect(() => () => {
    document.removeEventListener('keydown',   onKeyDown);
    document.removeEventListener('mousemove', onMouseMove);
    document.removeEventListener('scroll',    onScroll, true);
  }, [onKeyDown, onMouseMove, onScroll]);

  // ── Cities ────────────────────────────────────────────────────────────────
  useEffect(() => {
    req(`${INTEL}/demo/city-list`, 'GET', null, false).then(r => {
      if (r.ok && r.data?.cities) setCities(r.data.cities.map(c => c.name));
    });
    if (getToken()) intelGetTrust();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // ── Trust ─────────────────────────────────────────────────────────────────
  const intelGetTrust = async () => {
    if (!getToken()) return;
    setLoad('trust', true);
    const r = await req(`${INTEL}/trust-score`);
    setTrustResp(r);
    if (r.ok && r.data) {
      setTrust({ score: r.data.trust_score, label: r.data.label, color: r.data.color });
      setTrustHist(r.data.history || []);
    }
    setLoad('trust', false);
  };
  const intelVerify = async () => {
    if (!getToken()) { alert('Login first.'); return; }
    setLoad('verify', true);
    const r = await req(`${INTEL}/continuous-verify`, 'POST', {});
    setTrustResp(r);
    if (r.ok) setTrust({ score: r.data.trust_score, label: r.data.label, color: r.data.color });
    setLoad('verify', false);
  };
  const intelDropTrust = async () => {
    if (!getToken()) { alert('Login first (use Quick Login above).'); return; }
    setLoad('drop', true);
    const r = await req(`${INTEL}/simulate-trust-drop`, 'POST', { target_score: 25, reason: 'Manual demo drop' });
    setTrustResp(r);
    if (r.ok && r.data) {
      setTrust({ score: r.data.new_trust, label: r.data.trust_label, color: r.data.trust_color });
    }
    setLoad('drop', false);
  };

  // ── Quick Login ───────────────────────────────────────────────────────────
  const quickLogin = async () => {
    setLoad('ql', true);
    const r = await req(`${AUTH}/login`, 'POST', { email: 'demo.user@adaptive.demo', password: 'DemoUser@123!' }, false);
    if (r.ok && r.data?.access_token) {
      saveToken(r.data.access_token);
      onTokenSave?.();
      setLoginStatus('✅ Logged in as demo.user@adaptive.demo');
      await intelGetTrust();
    } else {
      setLoginStatus('❌ Login failed — run Setup in Scenario 1 first.');
    }
    setLoad('ql', false);
  };

  // ── Behavior Send ─────────────────────────────────────────────────────────
  const sendBehavior = async () => {
    if (!getToken()) { alert('Login first.'); return; }
    const s = computeScores();
    setBhScores(s);
    setLoad('beh', true);
    const r = await req(`${INTEL}/behavior-signal`, 'POST', {
      typing_entropy: s.te, mouse_linearity: s.ml, scroll_variance: s.sv, local_risk_score: s.lr,
    });
    setBehavResp(r);
    if (r.ok && r.data?.trust) {
      setTrust({ score: r.data.trust.score, label: r.data.trust.label, color: r.data.trust.color });
    }
    setLoad('beh', false);
  };

  // ── Travel ────────────────────────────────────────────────────────────────
  const checkTravel = async () => {
    setLoad('travel', true);
    const r = await req(`${INTEL}/demo/impossible-travel`, 'POST', {
      from_city: travelFrom, to_city: travelTo,
      time_gap_hours: parseFloat(travelHours), from_country: '', to_country: '',
    }, false);
    setTravelResult(r.ok ? r.data : null);
    setLoad('travel', false);
  };

  // ── AI Anomaly ────────────────────────────────────────────────────────────
  const scoreAnomaly = async () => {
    setLoad('ai', true);
    const r = await req(`${INTEL}/demo/anomaly-score`, 'POST', {
      typing_entropy:       parseFloat(aiTyping),
      mouse_linearity:      parseFloat(aiMouse),
      scroll_variance:      parseFloat(aiScroll),
      hour_normalized:      parseFloat(aiHour),
      failed_attempts_norm: parseFloat(aiFailed),
    }, false);
    setAnomResult(r.ok ? r.data : null);
    setLoad('ai', false);
  };

  // ── Micro-Challenge ───────────────────────────────────────────────────────
  const generateChallenge = async () => {
    if (!getToken()) {
      const a = Math.floor(Math.random() * 9) + 2, b = Math.floor(Math.random() * 9) + 2;
      setChallengeId('demo-no-auth');
      setChallengeQ(`What is ${a} × ${b} ?`);
      setChallengeAnswer('');
      setChallengeMsg('(Demo mode — login to persist trust changes)');
      setShowChallenge(true);
      return;
    }
    setLoad('ch', true);
    const r = await req(`${INTEL}/micro-challenge/generate`, 'POST', {});
    setChallengeResp(r);
    if (r.ok && r.data?.challenge) {
      setChallengeId(r.data.challenge.challenge_id);
      setChallengeQ(r.data.challenge.question);
      setChallengeAnswer('');
      setChallengeMsg(r.data.challenge_needed ? '' : 'ℹ Trust is healthy — showing challenge for demo purposes.');
      setShowChallenge(true);
    }
    setLoad('ch', false);
  };

  const verifyChallenge = async () => {
    if (!challengeAnswer.trim()) { alert('Enter your answer.'); return; }
    if (!challengeId || challengeId === 'demo-no-auth') {
      setChallengeMsg('✅ Submitted (login to update real trust score).');
      setShowChallenge(false);
      return;
    }
    setLoad('chv', true);
    const r = await req(`${INTEL}/micro-challenge/verify`, 'POST', { challenge_id: challengeId, response: challengeAnswer });
    setChallengeResp(r);
    if (r.ok && r.data) {
      setChallengeMsg(r.data.reason);
      if (r.data.correct) {
        setShowChallenge(false);
        setTrust({ score: r.data.new_trust, label: r.data.trust_label, color: r.data.trust_color });
      } else {
        setChallengeAnswer('');
      }
    }
    setLoad('chv', false);
  };

  // ── Explain ───────────────────────────────────────────────────────────────
  const explainRisk = async () => {
    setLoad('exp', true);
    const r = await req(`${INTEL}/demo/explain`, 'POST', {
      location_score: parseFloat(expLoc), device_score: parseFloat(expDev),
      time_score: parseFloat(expTime),    velocity_score: parseFloat(expVel),
      behavior_score: parseFloat(expBeh), security_level: parseInt(expLevel),
      risk_level: 'medium',
    }, false);
    setExplainResult(r.ok ? r.data : null);
    setLoad('exp', false);
  };

  return (
    <div>
      <Callout type="info">
        <strong>🧠 Session Intelligence — 8 Advanced Security Features</strong><br />
        Continuous Verification &bull; Behavioral Intelligence &bull; Dynamic Trust Score &bull;
        Micro-Challenges &bull; Explainability &bull; AI Anomaly Detection &bull; Impossible Travel &bull;
        Privacy-First Design.
      </Callout>

      {/* Quick Login */}
      <Card>
        <CardHeader icon="🔑">Session Authentication</CardHeader>
        <div className="flex items-center gap-3 flex-wrap">
          <span className="text-sm text-muted">Protected features require a JWT token.</span>
          <button className="btn btn-primary btn-sm" onClick={quickLogin} disabled={loading.ql}>
            {loading.ql ? '…' : '⚡ Quick Login (demo user)'}
          </button>
          {loginStatus && (
            <span className="text-sm" style={{ color: loginStatus.startsWith('✅') ? 'var(--success)' : 'var(--danger)' }}>
              {loginStatus}
            </span>
          )}
        </div>
      </Card>

      {/* Trust Score */}
      <Card>
        <CardHeader icon="🛡️">Dynamic Trust Score &amp; Continuous Verification</CardHeader>
        <div className="flex gap-4 flex-wrap items-start">
          <TrustGauge score={trust.score} label={trust.label} color={trust.color} />
          <div style={{ flex: 1, minWidth: 180 }}>
            <div className="flex gap-2 flex-wrap mb-3">
              <button className="btn btn-ghost btn-sm" onClick={intelGetTrust}  disabled={loading.trust}>🔄 Refresh</button>
              <button className="btn btn-ghost btn-sm" onClick={intelVerify}    disabled={loading.verify}>✔ Verify Now</button>
              <button className="btn btn-warn btn-sm"  onClick={intelDropTrust} disabled={loading.drop}>🔽 Drop to 25</button>
            </div>
            {trustHistory.length > 0 && (
              <div>
                <div className="text-xs font-600 uppercase letter-wide text-muted mb-2">Recent Trust Events</div>
                <div style={{ maxHeight: 130, overflowY: 'auto' }}>
                  {[...trustHistory].reverse().slice(0, 20).map((e, i) => (
                    <div key={i} className="flex justify-between text-xs" style={{ borderBottom: '1px solid var(--border)', padding: '2px 0' }}>
                      <span className="text-muted">{e.event_type}</span>
                      <span style={{ color: e.delta >= 0 ? 'var(--success)' : 'var(--danger)' }}>
                        {e.delta >= 0 ? '+' : ''}{e.delta.toFixed(1)} → {e.score.toFixed(0)}
                      </span>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>
        <ResponseBox result={trustResp} />
      </Card>

      {/* Behavior Intelligence */}
      <Card>
        <CardHeader icon="🔒">Privacy-First Behavioral Intelligence</CardHeader>
        <div className="callout callout-info text-sm mb-3" style={{ padding: '8px 12px' }}>
          <strong>🔒 Privacy-First:</strong> Keystroke timings, mouse coords and scroll deltas are processed{' '}
          <em>entirely in-browser</em>. Only the aggregated 0–1 scores are sent to the server.
        </div>
        <div className="flex gap-2 flex-wrap mb-3 items-center">
          <button
            className={`btn btn-sm ${collecting ? 'btn-danger' : 'btn-success'}`}
            onClick={collecting ? stopCollecting : startCollecting}
          >
            {collecting ? '⏹ Stop Collecting' : '▶ Start Collecting'}
          </button>
          <button className="btn btn-primary btn-sm" onClick={sendBehavior} disabled={loading.beh}>
            📤 Send Signals
          </button>
          {collectStatus && <span className="text-xs text-muted">{collectStatus}</span>}
        </div>
        <BehaviorBar label="⌨️ Typing Entropy (1.0 = human-like rhythm)"   value={bhScores.te} />
        <BehaviorBar label="🖱️ Mouse Linearity (1.0 = curved/natural)"      value={bhScores.ml} />
        <BehaviorBar label="📜 Scroll Variance (0.5 = organic human rhythm)" value={bhScores.sv} />
        <ResponseBox result={behaviorResp} />
      </Card>

      <div className="grid-2">
        {/* Impossible Travel */}
        <Card style={{ margin: 0 }}>
          <CardHeader icon="✈️">Impossible Travel Detector</CardHeader>
          <div className="grid-2 mb-2">
            <FormGroup label="FROM City">
              <select value={travelFrom} onChange={e => setTravelFrom(e.target.value)}>
                {cities.map(c => <option key={c}>{c}</option>)}
              </select>
            </FormGroup>
            <FormGroup label="TO City">
              <select value={travelTo} onChange={e => setTravelTo(e.target.value)}>
                {cities.map(c => <option key={c}>{c}</option>)}
              </select>
            </FormGroup>
          </div>
          <FormGroup label="Time gap (hours)">
            <input type="number" value={travelHours} onChange={e => setTravelHours(e.target.value)} min="0.01" step="0.5" />
          </FormGroup>
          <button className="btn btn-primary btn-sm btn-full" onClick={checkTravel} disabled={loading.travel}>
            {loading.travel ? '…' : '📏 Calculate Travel Risk'}
          </button>
          <TravelResult data={travelResult} />
        </Card>

        {/* AI Anomaly Scorer */}
        <Card style={{ margin: 0 }}>
          <CardHeader icon="🤖">AI Anomaly Scorer</CardHeader>
          {[
            { label: 'Typing entropy',         val: aiTyping,  set: setAiTyping },
            { label: 'Mouse linearity',         val: aiMouse,   set: setAiMouse  },
            { label: 'Scroll variance',         val: aiScroll,  set: setAiScroll },
            { label: 'Hour normalized',         val: aiHour,    set: setAiHour   },
            { label: 'Failed attempts (÷20)',   val: aiFailed,  set: setAiFailed },
          ].map(f => (
            <div key={f.label} className="flex items-center justify-between gap-2 mb-2">
              <span className="text-sm text-2">{f.label}</span>
              <input
                type="number" value={f.val} onChange={e => f.set(e.target.value)}
                min="0" max="1" step="0.05"
                style={{ width: 72, textAlign: 'right', padding: '3px 6px' }}
              />
            </div>
          ))}
          <button className="btn btn-primary btn-sm btn-full mt-2" onClick={scoreAnomaly} disabled={loading.ai}>
            {loading.ai ? '…' : '🧠 Score with AI'}
          </button>
          <AnomalyResult data={anomResult} />
        </Card>
      </div>

      {/* Micro-Challenges */}
      <Card>
        <CardHeader icon="🧩">Low-Friction Micro-Challenges</CardHeader>
        <p className="text-sm text-muted mb-3">
          Challenges fire <em>only when trust drops below 40</em> — never interrupts a trusted session.
        </p>
        <div className="flex gap-2 flex-wrap mb-3">
          <button className="btn btn-warn btn-sm"    onClick={intelDropTrust}    disabled={loading.drop}>🔽 Drop Trust to 25</button>
          <button className="btn btn-primary btn-sm" onClick={generateChallenge} disabled={loading.ch}>🧩 Generate Challenge</button>
        </div>
        {showChallenge && (
          <div className="callout callout-info">
            <div className="font-bold mb-2" style={{ fontSize: 16 }}>{challengeQ}</div>
            <div className="flex gap-2 items-center">
              <input
                type="text"
                value={challengeAnswer}
                onChange={e => setChallengeAnswer(e.target.value)}
                placeholder="Your answer…"
                style={{ width: 160 }}
              />
              <button className="btn btn-success btn-sm" onClick={verifyChallenge} disabled={loading.chv}>
                {loading.chv ? '…' : '✔ Verify'}
              </button>
            </div>
            {challengeMsg && <div className="text-sm mt-2">{challengeMsg}</div>}
          </div>
        )}
        <ResponseBox result={challengeResp} />
      </Card>

      {/* Explainability */}
      <Card>
        <CardHeader icon="📊">Explainable Risk Transparency</CardHeader>
        <p className="text-sm text-muted mb-3">
          Submit factor scores and see exactly which signals contributed and why — with model weights.
        </p>
        <div className="grid-3 mb-3">
          {[
            { label: '🌍 Location (0-100)',   val: expLoc,   set: setExpLoc,   max: 100 },
            { label: '💻 Device',             val: expDev,   set: setExpDev,   max: 100 },
            { label: '🕐 Time',               val: expTime,  set: setExpTime,  max: 100 },
            { label: '⚡ Velocity',            val: expVel,   set: setExpVel,   max: 100 },
            { label: '🧠 Behavior',            val: expBeh,   set: setExpBeh,   max: 100 },
            { label: '🔒 Security level (0-4)',val: expLevel, set: setExpLevel, max: 4 },
          ].map(f => (
            <FormGroup key={f.label} label={f.label}>
              <input type="number" value={f.val} onChange={e => f.set(e.target.value)} min="0" max={f.max} />
            </FormGroup>
          ))}
        </div>
        <button className="btn btn-primary btn-sm" onClick={explainRisk} disabled={loading.exp}>
          {loading.exp ? '…' : '🔍 Generate Explanation'}
        </button>
        {explainResult && (
          <div className="mt-3">
            <div className="text-sm text-muted mb-2">
              🔍 Audit ID: <code>{explainResult.audit_id}</code> &nbsp;·&nbsp;
              Confidence: {(explainResult.confidence * 100).toFixed(0)}% &nbsp;·&nbsp;
              Action: <em>{explainResult.action}</em>
            </div>
            <div className="resp-box" style={{ background: 'var(--surface-2)' }}>{explainResult.summary}</div>
            {(explainResult.factors || []).map(f => {
              const col = f.status === 'anomalous' ? '#dc2626' : '#16a34a';
              const bar = Math.min(100, Math.max(0, Math.abs(f.contribution) * 4));
              return (
                <div key={f.factor} className="factor-row mt-2">
                  <div className="factor-label">
                    <span>{f.icon} <strong>{f.factor}</strong> <span className="text-xs text-muted">w:{f.model_weight}</span></span>
                    <span style={{ color: col }}>{f.contribution >= 0 ? '+' : ''}{f.contribution.toFixed(1)}</span>
                  </div>
                  <div className="factor-bar-wrap">
                    <div className="factor-bar" style={{ width: `${bar}%`, background: col }} />
                  </div>
                  <div className="text-xs text-muted mt-1">{f.detail}</div>
                </div>
              );
            })}
          </div>
        )}
      </Card>

      {/* Session Audit Trail */}
      <Card>
        <CardHeader icon="📋">Session Audit Trail <span className="text-sm text-muted font-400">(requires login)</span></CardHeader>
        <button className="btn btn-ghost btn-sm mb-2" onClick={async () => {
          if (!getToken()) { alert('Login first.'); return; }
          setLoad('audit', true);
          setSessionResp(await req(`${INTEL}/explain`));
          setLoad('audit', false);
        }} disabled={loading.audit}>
          {loading.audit ? '…' : '📄 Fetch My Session Events'}
        </button>
        <ResponseBox result={sessionResp} />
      </Card>
    </div>
  );
}
