// Live transaction feed widget — rows stream in top to bottom with decision pills.
function LiveFeed({ rows: initialRows, interval = 1800, max = 8, compact = false }) {
  const pool = React.useMemo(() => initialRows || [
    { id: 'pay_01K5Z0QXM3', client: 'inxy_main',  amt: '4,820',  ccy: 'USDT', score: 92, dec: 'BLOCK',   reason: 'IP blocklist · velocity' },
    { id: 'pay_01K5Z0PN7C', client: 'inxy_main',  amt: '180',    ccy: 'USDT', score: 8,  dec: 'APPROVE', reason: 'known IP · in hours' },
    { id: 'pay_01K5Z0P4BX', client: 'acme_eu',    amt: '12,500', ccy: 'USDT', score: 64, dec: 'REVIEW',  reason: 'new destination' },
    { id: 'pay_01K5Z0NNF9', client: 'acme_eu',    amt: '280',    ccy: 'EUR',  score: 4,  dec: 'APPROVE', reason: 'whitelisted' },
    { id: 'pay_01K5Z0N2AA', client: 'lumen_labs', amt: '940',    ccy: 'USDT', score: 88, dec: 'BLOCK',   reason: 'sanctioned country' },
    { id: 'pay_01K5Z0MDLR', client: 'inxy_main',  amt: '72',     ccy: 'USDT', score: 23, dec: 'APPROVE', reason: 'low risk' },
    { id: 'pay_01K5Z0LY17', client: 'nimbus_pay', amt: '26,800', ccy: 'USDT', score: 71, dec: 'REVIEW',  reason: 'amount > 2× baseline' },
    { id: 'pay_01K5Z0KC7E', client: 'inxy_main',  amt: '650',    ccy: 'USDT', score: 94, dec: 'BLOCK',   reason: 'IP blocklist' },
    { id: 'pay_01K5Z0K019', client: 'acme_eu',    amt: '9,200',  ccy: 'USDT', score: 58, dec: 'REVIEW',  reason: 'anonymizer' },
    { id: 'pay_01K5Z0J4ZZ', client: 'nimbus_pay', amt: '120',    ccy: 'USDT', score: 34, dec: 'APPROVE', reason: 'familiar pattern' },
  ], [initialRows]);

  const [rows, setRows] = React.useState(() => pool.slice(0, max).map((r, i) => ({ ...r, _k: i, _age: i })));
  const [seed, setSeed] = React.useState(max);

  React.useEffect(() => {
    const t = setInterval(() => {
      setSeed(s => s + 1);
      const next = pool[seed % pool.length];
      setRows(prev => [{ ...next, _k: seed + 10000, _age: 0 }, ...prev.slice(0, max - 1)].map((r, i) => ({ ...r, _age: i })));
    }, interval);
    return () => clearInterval(t);
  }, [seed, pool, interval, max]);

  const now = () => {
    const d = new Date();
    return d.toTimeString().slice(0, 8);
  };

  return (
    <div className="lfeed">
      <div className="lfeed-head">
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span className="lfeed-dot" />
          <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'var(--fg-muted)', fontWeight: 600 }}>Live feed</span>
        </div>
        <span className="mono" style={{ fontSize: 11, color: 'var(--fg-muted)' }}>sandbox.eu-west-1</span>
      </div>
      <div className="lfeed-table">
        <div className="lfeed-header-row">
          <span>Time</span>
          <span>Transaction</span>
          <span style={{ textAlign: 'right' }}>Amount</span>
          <span style={{ textAlign: 'center' }}>Score</span>
          <span style={{ textAlign: 'center' }}>Verdict</span>
        </div>
        {rows.map(r => (
          <div key={r._k} className="lfeed-row" data-age={r._age}>
            <span className="mono lfeed-t">{now()}</span>
            <span>
              <div className="mono lfeed-id">{r.id}</div>
              {!compact && <div className="lfeed-sub">{r.client} · {r.reason}</div>}
            </span>
            <span className="mono lfeed-amt">
              {r.amt}<span style={{ color: 'var(--fg-muted)', marginLeft: 4, fontSize: 11 }}>{r.ccy}</span>
            </span>
            <span className={'mono lfeed-score lfeed-score-' + (r.score > 70 ? 'block' : r.score > 40 ? 'review' : 'approve')}>
              {r.score}
            </span>
            <span style={{ textAlign: 'center' }}>
              <span className={'pill pill-' + (r.dec === 'APPROVE' ? 'approve' : r.dec === 'REVIEW' ? 'review' : 'block')}>{r.dec}</span>
            </span>
          </div>
        ))}
      </div>
      <style>{`
        .lfeed {
          background: var(--surface-strong);
          border: 1px solid var(--border-strong);
          border-radius: 16px;
          overflow: hidden;
          backdrop-filter: blur(10px);
        }
        .lfeed-head {
          display: flex; justify-content: space-between; align-items: center;
          padding: 10px 16px;
          background: rgba(255,255,255,0.02);
          border-bottom: 1px solid var(--border);
        }
        .lfeed-dot {
          width: 8px; height: 8px; border-radius: 50%;
          background: var(--approve);
          box-shadow: 0 0 0 0 rgba(101,217,124,0.6);
          animation: lfeed-pulse 1.8s ease-out infinite;
        }
        @keyframes lfeed-pulse {
          0% { box-shadow: 0 0 0 0 rgba(101,217,124,0.55); }
          70% { box-shadow: 0 0 0 8px rgba(101,217,124,0); }
          100% { box-shadow: 0 0 0 0 rgba(101,217,124,0); }
        }
        .lfeed-header-row, .lfeed-row {
          display: grid;
          grid-template-columns: 80px 1fr 100px 60px 96px;
          gap: 12px;
          padding: 10px 16px;
          align-items: center;
          font-size: 12.5px;
          border-bottom: 1px solid var(--border);
        }
        .lfeed-header-row {
          font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em;
          color: var(--fg-muted); font-weight: 600;
          background: rgba(255,255,255,0.015);
        }
        .lfeed-row { transition: background 200ms; animation: lfeed-in 380ms cubic-bezier(.2,.9,.2,1); }
        @keyframes lfeed-in {
          0% { opacity: 0; transform: translateY(-8px); background: rgba(147,135,255,0.10); }
          100% { opacity: 1; transform: translateY(0); background: transparent; }
        }
        .lfeed-row:last-child { border-bottom: 0; }
        .lfeed-t { color: var(--fg-muted); font-size: 11px; }
        .lfeed-id { color: var(--fg); font-size: 12.5px; }
        .lfeed-sub { color: var(--fg-muted); font-size: 11px; margin-top: 2px; }
        .lfeed-amt { text-align: right; font-weight: 500; }
        .lfeed-score { text-align: center; font-weight: 600; }
        .lfeed-score-approve { color: var(--approve); }
        .lfeed-score-review { color: var(--review); }
        .lfeed-score-block { color: var(--block); }
      `}</style>
    </div>
  );
}

// Small score dial component for bold variant "live" widgets
function ScoreDial({ score, size = 160, label = 'Risk' }) {
  const tone = score > 70 ? '#FF5E78' : score > 40 ? '#FFB547' : '#65D97C';
  const pct = Math.max(0, Math.min(100, score));
  const C = 2 * Math.PI * 54;
  const off = C - (pct / 100) * C * 0.78;
  return (
    <div style={{ width: size, height: size, position: 'relative' }}>
      <svg width={size} height={size} viewBox="0 0 120 120" style={{ transform: 'rotate(-216deg)' }}>
        <circle cx="60" cy="60" r="54" stroke="rgba(255,255,255,0.08)" strokeWidth="8" fill="none"
          strokeDasharray={C * 0.78 + ' ' + (C - C * 0.78)} strokeLinecap="round" />
        <circle cx="60" cy="60" r="54" stroke={tone} strokeWidth="8" fill="none"
          strokeDasharray={C * 0.78 + ' ' + (C - C * 0.78)} strokeDashoffset={off}
          strokeLinecap="round"
          style={{ transition: 'stroke-dashoffset 600ms cubic-bezier(.2,.9,.2,1)' }}
        />
      </svg>
      <div style={{
        position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column',
      }}>
        <span className="mono" style={{ fontSize: size * 0.22, fontWeight: 700, color: tone, lineHeight: 1 }}>{pct}</span>
        <span style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.12em', color: 'var(--fg-muted)', marginTop: 6, fontWeight: 600 }}>{label}</span>
      </div>
    </div>
  );
}

Object.assign(window, { LiveFeed, ScoreDial });
