// Shared hooks — number tween for stat counters + scoreClass / decisionClass helpers.

function useTween(target, opts = {}) {
  // Eased ease-out-cubic count-up animation; mirrors the imperative
  // `tween()` function from the legacy landing.html so the counters in
  // HeroMetric / MetricCard / DecisionPie / TopRules feel identical.
  const { duration = 1400, format = (n) => Math.round(n).toLocaleString('en-US') } = opts;
  const [display, setDisplay] = React.useState(format(0));
  React.useEffect(() => {
    let raf;
    const start = performance.now();
    const tick = (t) => {
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setDisplay(format(target * eased));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [target, duration]);
  return display;
}

function scoreClass(s) {
  return s <= 40 ? 'score-low' : s <= 70 ? 'score-mid' : 'score-hi';
}

function decisionClass(d) {
  return d === 'APPROVE' ? 'b-approve' : d === 'REVIEW' ? 'b-review' : 'b-block';
}

function decisionBadgeClass(d) {
  return d === 'APPROVE' ? 'dec-approve' : d === 'REVIEW' ? 'dec-review' : 'dec-block';
}

function nowTs() {
  return new Date().toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
}

function rulesCount(score) {
  if (score <= 40) return Math.random() < 0.5 ? 0 : 1;
  if (score <= 70) return 2 + Math.floor(Math.random() * 2);
  return 3 + Math.floor(Math.random() * 3);
}

// Live transaction generator — used by the Recent evaluations panel.
const TX_TEMPLATES = [
  { id: 'tx-2026-05-06-9a17', client: 'acme-19104', amt: '250.50 USDT',   score: 71, decision: 'BLOCK',   ip: '8.8.8.8' },
  { id: 'tx-2026-05-06-3c9d', client: 'acme-19104', amt: '12 540 USDT',   score: 53, decision: 'REVIEW',  ip: '185.156.72.10' },
  { id: 'tx-2026-05-06-f1b2', client: 'orbit-18769',amt: '2 435.13 USDT', score: 1,  decision: 'APPROVE', ip: '52.10.4.198' },
  { id: 'tx-2026-05-06-7e44', client: 'orbit-18769',amt: '57.20 USDT',    score: 4,  decision: 'APPROVE', ip: '34.224.18.7' },
  { id: 'tx-2026-05-06-0b21', client: 'lyra-20126', amt: '50 000 USDT',   score: 49, decision: 'REVIEW',  ip: '185.156.72.10' },
  { id: 'tx-2026-05-06-bb98', client: 'lyra-20126', amt: '87.75 USDT',    score: 0,  decision: 'APPROVE', ip: '3.122.14.91' },
  { id: 'tx-2026-05-06-5a02', client: 'apex-19104', amt: '1 480 USDT',    score: 28, decision: 'APPROVE', ip: '4.71.182.4' },
  { id: 'tx-2026-05-06-d7f3', client: 'apex-19104', amt: '3 472 USDT',    score: 64, decision: 'REVIEW',  ip: '5.255.232.201' },
];
