// Shared UI primitives — small, composable, no React deps
// Exposes window.UI = { Spark, MiniBar, CatPill, AmountCell, AccountPill, Sparkline }

(function() {
  function Spark({ points = [], w = 120, h = 28, stroke = 'currentColor', fill = null, strokeWidth = 1 }) {
    if (points.length < 2) return null;
    const min = Math.min(...points);
    const max = Math.max(...points);
    const rng = (max - min) || 1;
    const step = w / (points.length - 1);
    const pts = points.map((p, i) => [i * step, h - ((p - min) / rng) * (h - 2) - 1]);
    const d = pts.map((p, i) => (i === 0 ? 'M' : 'L') + p[0].toFixed(1) + ',' + p[1].toFixed(1)).join(' ');
    const area = fill ? `${d} L${w},${h} L0,${h} Z` : null;
    return (
      <svg width={w} height={h} className="spark" style={{ overflow: 'visible' }}>
        {area && <path d={area} fill={fill} opacity="0.12" />}
        <path d={d} fill="none" stroke={stroke} strokeWidth={strokeWidth} strokeLinejoin="round" strokeLinecap="round" />
      </svg>
    );
  }

  function Bars({ data, w = 360, h = 80, accessor }) {
    const vals = data.map(accessor);
    const max = Math.max(...vals.flat());
    const bw = w / data.length - 4;
    return (
      <svg width={w} height={h}>
        {data.map((d, i) => {
          const [a, b] = accessor(d); // [in, out]
          const x = i * (bw + 4);
          const ha = (a / max) * (h - 14);
          const hb = (b / max) * (h - 14);
          return (
            <g key={i}>
              <rect x={x} y={h - 14 - ha} width={bw/2 - 1} height={ha} fill="var(--pos)" opacity="0.85" />
              <rect x={x + bw/2 + 1} y={h - 14 - hb} width={bw/2 - 1} height={hb} fill="var(--neg)" opacity="0.85" />
              <text x={x + bw/2} y={h - 2} textAnchor="middle" fontSize="9" fontFamily="var(--font-mono)" fill="var(--fg-3)">{d.m}</text>
            </g>
          );
        })}
      </svg>
    );
  }

  function CatPill({ cat, small }) {
    const c = window.DATA.categories[cat];
    if (!c) return <span className="mono-label">{cat}</span>;
    return (
      <span className="cat-pill" style={{
        display: 'inline-flex', alignItems: 'center', gap: 6,
        fontFamily: 'var(--font-mono)', fontSize: small ? 10 : 11,
        textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--fg-1)',
        padding: small ? '1px 5px' : '2px 7px',
        border: '1px solid var(--line-2)', background: 'var(--bg-2)',
      }}>
        <span style={{ width: 6, height: 6, background: c.color, display: 'inline-block' }} />
        {c.label}
      </span>
    );
  }

  function Amount({ v, currency = 'USD' }) {
    const neg = v < 0;
    const s = Math.abs(v).toLocaleString('en-US', {
      minimumFractionDigits: currency === 'BTC' ? 4 : 2,
      maximumFractionDigits: currency === 'BTC' ? 8 : 2,
    });
    return (
      <span className="num" style={{ color: neg ? 'var(--fg-0)' : 'var(--pos)' }}>
        {neg ? '−' : '+'}{currency === 'USD' ? '$' : ''}{s}{currency !== 'USD' ? ' ' + currency : ''}
      </span>
    );
  }

  function AccountTag({ id }) {
    const a = window.DATA.accounts.find(x => x.id === id);
    if (!a) return null;
    return (
      <span className="mono" style={{ fontSize: 10, color: 'var(--fg-2)', textTransform: 'uppercase', letterSpacing: '0.1em' }}>
        {a.source} · {a.mask}
      </span>
    );
  }

  function Confidence({ c }) {
    const pct = Math.round(c * 100);
    const low = c < 0.75;
    return (
      <span className="mono" style={{
        fontSize: 10, color: low ? 'var(--cat-amber)' : 'var(--fg-2)',
        display: 'inline-flex', alignItems: 'center', gap: 4,
      }}>
        <span style={{
          width: 24, height: 3, background: 'var(--bg-3)', position: 'relative', overflow: 'hidden', display: 'inline-block',
        }}>
          <span style={{ position: 'absolute', inset: 0, width: pct + '%', background: low ? 'var(--cat-amber)' : 'var(--pos)' }} />
        </span>
        {pct}
      </span>
    );
  }

  window.UI = { Spark, Bars, CatPill, Amount, AccountTag, Confidence };
})();
