// Dashboard scene — 1:1 with the SOC console at app.dipoli.io/.
// HeroMetric + 3 MetricCards + VolumeChart + DecisionPie + RecentTransactions
// + TopRules. All number counters use useTween for the ease-out-cubic feel.

function DashboardScene({ active }) {
  return (
    <React.Fragment>
      <MockNav active="dash" />
      <div className="mock-page">
        <h2 className="mock-h1">Dashboard</h2>

        <div className="grid-5">
          <DashHero active={active} />
          <DashMetricCard variant="v-block"   label="Block rate"   target={4.6}  format={(n) => n.toFixed(1) + '%'} delta="▲ +0.4%" deltaUp icon={<MetricBlockIcon />} />
          <DashMetricCard variant="v-approve" label="Approved"     target={27842} delta="▲ +3.2%" deltaUp icon={<MetricApproveIcon />} />
          <DashMetricCard variant="v-review"  label="Review queue" target={1791}  delta="▼ -1.1%" icon={<MetricReviewIcon />} />
        </div>

        <div className="grid-3">
          <VolumeChartPanel />
          <DecisionPiePanel />
        </div>

        <div className="grid-3" style={{ marginTop: 12 }}>
          <RecentEvaluationsPanel active={active} />
          <TopRulesPanel />
        </div>
      </div>
    </React.Fragment>
  );
}

function DashHero({ active }) {
  const val = useTween(31065);
  return (
    <div className="hero-metric">
      <div className="scan-strip"></div>
      <div className="lbl">Evaluations (24h)</div>
      <div className="nrow">
        <span className="val">{val}</span>
        <span className="sub">transactions</span>
      </div>
      <svg className="rings" viewBox="0 0 220 220" fill="none">
        <circle cx="110" cy="110" r="100" stroke="white" strokeWidth="1" opacity="0.4"/>
        <circle cx="110" cy="110" r="75"  stroke="white" strokeWidth="1" opacity="0.35"/>
        <circle cx="110" cy="110" r="50"  stroke="white" strokeWidth="1" opacity="0.3"/>
        <circle cx="110" cy="110" r="25"  stroke="white" strokeWidth="1" opacity="0.25"/>
        <path d="M70 110 L95 135 L150 80" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" opacity="0.6"/>
      </svg>
    </div>
  );
}

function DashMetricCard({ variant, label, target, format, delta, deltaUp, icon }) {
  const val = useTween(target, format ? { format } : undefined);
  const color = variant === 'v-block' ? 'var(--block)' : variant === 'v-approve' ? 'var(--approve)' : 'var(--review)';
  return (
    <div className={'metric ' + variant}>
      <div className="top-bar"></div>
      <div className="head">
        <div className="meta">
          <div className="lbl">{label}</div>
          <div className="val">{val}</div>
        </div>
        <div className="icbox">{icon}</div>
      </div>
      <div className="delta" style={{ color }}>
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
          {deltaUp
            ? <React.Fragment><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></React.Fragment>
            : <React.Fragment><polyline points="22 17 13.5 8.5 8.5 13.5 2 7"/><polyline points="16 17 22 17 22 11"/></React.Fragment>}
        </svg>
        {delta.replace(/[▲▼]\s*/, '')}
        <span className="lab">vs yesterday</span>
      </div>
    </div>
  );
}

function MetricBlockIcon() {
  return <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M20 13c0 5-3.5 7.5-8 9-4.5-1.5-8-4-8-9V5l8-3 8 3z"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg>;
}

function MetricApproveIcon() {
  return <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M9 12l2 2 4-4"/><path d="M20 13c0 5-3.5 7.5-8 9-4.5-1.5-8-4-8-9V5l8-3 8 3z"/></svg>;
}

function MetricReviewIcon() {
  return <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>;
}

// ── Volume chart ─────────────────────────────────────────────────────
function VolumeChartPanel() {
  // 24-hour synthetic series — same easing curve the legacy chart used.
  const series = React.useMemo(() => {
    const pts = [];
    for (let i = 0; i < 24; i++) {
      const t = i / 23;
      const wave = Math.sin(t * Math.PI * 2) * 0.4 + 0.55;
      const noise = (Math.sin(i * 7.3) + 1) * 0.08;
      pts.push(Math.max(0.05, Math.min(0.95, wave - noise)));
    }
    return pts;
  }, []);

  const W = 700, H = 200, padL = 30, padR = 8, padT = 30, padB = 30;
  const innerW = W - padL - padR;
  const innerH = H - padT - padB;
  const xs = series.map((_, i) => padL + (i / (series.length - 1)) * innerW);
  const ys = series.map((v) => padT + (1 - v) * innerH);

  // Smooth path via cubic Bézier midpoints — keeps the line organic
  // without piling on dependencies.
  let path = `M ${xs[0]} ${ys[0]}`;
  for (let i = 1; i < xs.length; i++) {
    const cx = (xs[i - 1] + xs[i]) / 2;
    path += ` Q ${cx} ${ys[i - 1]} ${cx} ${(ys[i - 1] + ys[i]) / 2}`;
    path += ` Q ${cx} ${ys[i]} ${xs[i]} ${ys[i]}`;
  }
  const area = path + ` L ${xs[xs.length - 1]} ${padT + innerH} L ${xs[0]} ${padT + innerH} Z`;

  const labels = ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'];

  return (
    <div className="panel">
      <div className="orb tl c-primary"></div>
      <div className="panel-h">Transaction volume (24h)</div>
      <svg className="volume-svg" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none">
        <defs>
          <linearGradient id="fillVolume" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="#9387FF" stopOpacity="0.55"/>
            <stop offset="100%" stopColor="#9387FF" stopOpacity="0"/>
          </linearGradient>
        </defs>
        <g className="volume-grid">
          <line x1={padL} y1={padT + 10}              x2={W - padR} y2={padT + 10}/>
          <line x1={padL} y1={padT + innerH * 0.5}    x2={W - padR} y2={padT + innerH * 0.5}/>
          <line x1={padL} y1={padT + innerH}          x2={W - padR} y2={padT + innerH}/>
        </g>
        <g className="volume-axis">
          {labels.map((l, i) => (
            <text key={l} x={padL + (i / (labels.length - 1)) * innerW} y={H - 8} textAnchor="middle">{l}</text>
          ))}
        </g>
        <path className="volume-area" d={area} />
        <path className="volume-line" d={path} />
      </svg>
    </div>
  );
}

// ── Decision pie ────────────────────────────────────────────────────
function DecisionPiePanel() {
  const total = 31065;
  const dist = {
    APPROVE: { count: 27842, color: 'var(--approve)' },
    REVIEW:  { count: 1791,  color: 'var(--review)'  },
    BLOCK:   { count: 1432,  color: 'var(--block)'   },
  };

  // Arc length on r=40 ⇒ circumference 2πr ≈ 251.3. Each segment gets
  // a stroke-dasharray "len gap" and a rotation offset based on the
  // cumulative count.
  const circ = 2 * Math.PI * 40;
  const order = ['APPROVE', 'REVIEW', 'BLOCK'];
  let acc = 0;
  const arcs = order.map((k) => {
    const frac = dist[k].count / total;
    const len = frac * circ;
    const rotateDeg = -90 + (acc / total) * 360;
    acc += dist[k].count;
    return { k, len, rotateDeg, color: dist[k].color };
  });

  // Pretty-print percent + count tween.
  const a = useTween(dist.APPROVE.count);
  const r = useTween(dist.REVIEW.count);
  const b = useTween(dist.BLOCK.count);

  return (
    <div className="panel">
      <div className="orb tr c-approve"></div>
      <div className="panel-h">Decision distribution</div>
      <div className="pie-row">
        <svg className="pie-svg" viewBox="0 0 100 100">
          <circle cx="50" cy="50" r="40" fill="none" stroke="rgba(255,255,255,0.05)" strokeWidth="14"/>
          {arcs.map(({ k, len, rotateDeg, color }) => (
            <circle
              key={k}
              cx="50" cy="50" r="40" fill="none"
              stroke={color}
              strokeWidth="14"
              strokeDasharray={`${len} ${circ - len}`}
              transform={`rotate(${rotateDeg} 50 50)`}
            />
          ))}
        </svg>
        <div className="legend">
          {[
            { name: 'APPROVE', val: a, pct: ((dist.APPROVE.count / total) * 100).toFixed(1) + '%', color: 'var(--approve)' },
            { name: 'REVIEW',  val: r, pct: ((dist.REVIEW.count  / total) * 100).toFixed(1) + '%', color: 'var(--review)'  },
            { name: 'BLOCK',   val: b, pct: ((dist.BLOCK.count   / total) * 100).toFixed(1) + '%', color: 'var(--block)'   },
          ].map((row) => (
            <div key={row.name} className="legend-row">
              <span className="lf"><span className="swatch" style={{ background: row.color }}></span>{row.name}</span>
              <span>{row.val}<span className="pct">{row.pct}</span></span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── Recent evaluations table ─────────────────────────────────────────
function RecentEvaluationsPanel({ active }) {
  // Initial 6 rows + a live appended row every ~3s while the scene is on.
  const [rows, setRows] = React.useState(() =>
    TX_TEMPLATES.slice(0, 6).map((t) => ({ ...t, ts: nowTs(), anim: false }))
  );

  React.useEffect(() => {
    if (!active) return;
    const id = setInterval(() => {
      const t = TX_TEMPLATES[Math.floor(Math.random() * TX_TEMPLATES.length)];
      const s = Math.max(0, Math.min(99, t.score + Math.floor(Math.random() * 14) - 7));
      const d = s > 70 ? 'BLOCK' : s > 40 ? 'REVIEW' : 'APPROVE';
      const fresh = {
        id: `tx-2026-05-06-${Math.random().toString(16).slice(2, 6)}`,
        client: t.client, amt: t.amt, ip: t.ip,
        score: s, decision: d, ts: nowTs(), anim: true,
      };
      setRows((prev) => [fresh, ...prev].slice(0, 7));
    }, 3500);
    return () => clearInterval(id);
  }, [active]);

  return (
    <div className="panel">
      <div className="orb tl c-block"></div>
      <div className="panel-h">Recent evaluations</div>
      <table className="tx">
        <thead><tr>
          <th>Time</th>
          <th className="mono">TX ID</th>
          <th>Client</th>
          <th style={{ textAlign: 'right' }}>Amount</th>
          <th style={{ textAlign: 'center' }}>Score</th>
          <th style={{ textAlign: 'center' }}>Rules</th>
          <th style={{ textAlign: 'center' }}>Decision</th>
        </tr></thead>
        <tbody>
          {rows.map((row, i) => (
            <tr key={row.id + i} className={row.anim ? 'row-anim' : ''}>
              <td className="mono" style={{ color: 'var(--ink-mute)' }}>{row.ts}</td>
              <td className="mono">{row.id}</td>
              <td>{row.client}</td>
              <td className="mono" style={{ textAlign: 'right' }}>{row.amt}</td>
              <td style={{ textAlign: 'center' }}>
                <span className={scoreClass(row.score)}>{row.score}</span>
              </td>
              <td style={{ textAlign: 'center', color: 'var(--ink-mute)' }}>{rulesCount(row.score)}</td>
              <td style={{ textAlign: 'center' }}>
                <span className={'badge ' + decisionClass(row.decision)}>{row.decision}</span>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// ── Top triggered signals ────────────────────────────────────────────
function TopRulesPanel() {
  const RULES = [
    { name: 'High frequency · 1h',  target: 412, pct: 100 },
    { name: 'Sanctioned country',   target: 287, pct: 69 },
    { name: 'Anonymous network',    target: 194, pct: 47 },
    { name: 'New IP address',       target: 142, pct: 34 },
    { name: 'Amount anomaly',       target: 98,  pct: 24 },
  ];
  return (
    <div className="panel">
      <div className="orb br c-review"></div>
      <div className="panel-h">Top triggered signals</div>
      <div>
        {RULES.map((r) => <TopRuleRow key={r.name} {...r} />)}
      </div>
    </div>
  );
}

function TopRuleRow({ name, target, pct }) {
  const n = useTween(target);
  const [w, setW] = React.useState(0);
  React.useEffect(() => {
    const id = requestAnimationFrame(() => setW(pct));
    return () => cancelAnimationFrame(id);
  }, [pct]);
  return (
    <div className="rule">
      <div className="rule-row">
        <span>{name}</span>
        <span className="mono">{n}</span>
      </div>
      <div className="rule-bar"><span style={{ width: w + '%' }}></span></div>
    </div>
  );
}
