// components.jsx — themed M3 UI kit + phone shell. -> window.
// Relies on CSS vars set by themeVars() on an ancestor. Money in cents.

// (hooks referenced as React.useX to avoid classic-script global collisions)

// One-time global CSS: keyframes, slider internals, pressable feedback, toast.
(function injectAppCss() {
  if (document.getElementById('ta-css')) return;
  const s = document.createElement('style');
  s.id = 'ta-css';
  s.textContent = `
  .ta-root *{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
  .ta-press{transition:transform .12s cubic-bezier(.2,.7,.3,1), filter .12s, background .15s, box-shadow .15s}
  .ta-press:active{transform:scale(.965)}
  .ta-scroll{overflow-y:auto;scrollbar-width:none}
  .ta-scroll::-webkit-scrollbar{display:none}
  .ta-fade{animation:taFade .32s cubic-bezier(.2,.7,.3,1)}
  @keyframes taFade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
  .ta-pop{animation:taPop .34s cubic-bezier(.2,.8,.25,1)}
  @keyframes taPop{from{opacity:0;transform:scale(.9)}to{opacity:1;transform:none}}
  .ta-sheet-in{animation:taSheet .34s cubic-bezier(.2,.8,.25,1)}
  @keyframes taSheet{from{transform:translateY(102%)}to{transform:none}}
  .ta-toast-in{animation:taToast .3s cubic-bezier(.2,.8,.25,1)}
  @keyframes taToast{from{opacity:0;transform:translateY(14px) scale(.96)}to{opacity:1;transform:none}}
  @keyframes taScan{0%{top:6%}50%{top:90%}100%{top:6%}}
  @keyframes taSpin{to{transform:rotate(360deg)}}
  .ta-shimmer{background:linear-gradient(100deg,var(--surface-variant) 30%,var(--outline-faint) 50%,var(--surface-variant) 70%);background-size:200% 100%;animation:taShim 1.2s infinite}
  @keyframes taShim{to{background-position:-200% 0}}
  .ta-num{font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1}
  `;
  document.head.appendChild(s);
})();

// ── Phone shell ───────────────────────────────────────────────
function StatusBar({ tint }) {
  return (
    <div style={{ height: 34, flexShrink: 0, display: 'flex', alignItems: 'center',
      justifyContent: 'space-between', padding: '0 18px 0 22px', color: tint, position: 'relative' }}>
      <span className="ta-num" style={{ fontSize: 14, fontWeight: 600, letterSpacing: 0.2 }}>9:41</span>
      <div style={{ position: 'absolute', left: '50%', top: 9, transform: 'translateX(-50%)',
        width: 11, height: 11, borderRadius: 99, background: '#000', opacity: 0.85 }} />
      <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
        <svg width="17" height="11" viewBox="0 0 17 11" fill={tint}><rect x="0" y="7" width="3" height="4" rx="1"/><rect x="4.5" y="5" width="3" height="6" rx="1"/><rect x="9" y="2.5" width="3" height="8.5" rx="1"/><rect x="13.5" y="0" width="3" height="11" rx="1" opacity="0.4"/></svg>
        <svg width="16" height="11" viewBox="0 0 16 11" fill={tint}><path d="M8 2.2c1.9 0 3.6.7 4.9 1.9l1.1-1.2A9 9 0 008 1.5 9 9 0 002 2.9L3.1 4A7 7 0 018 2.2z" opacity="0.9"/><path d="M8 5c1 0 2 .4 2.7 1.1l1.1-1.2A6 6 0 008 4.3 6 6 0 004.2 4.9L5.3 6.1A4 4 0 018 5z"/><circle cx="8" cy="8.4" r="1.6"/></svg>
        <svg width="26" height="13" viewBox="0 0 26 13" fill="none"><rect x="0.6" y="0.6" width="21" height="11.8" rx="3" stroke={tint} strokeOpacity="0.5"/><rect x="2.2" y="2.2" width="15" height="8.6" rx="1.6" fill={tint}/><rect x="23" y="4" width="1.8" height="5" rx="0.9" fill={tint} fillOpacity="0.5"/></svg>
      </div>
    </div>
  );
}

function PhoneShell({ theme, children, width = 372, height = 786 }) {
  const t = theme.tok;
  return (
    <div className="ta-root" style={{
      width, height, borderRadius: 44, overflow: 'hidden', position: 'relative',
      background: t.bg, color: t.onSurface, fontFamily: theme.fontBody,
      fontSize: `calc(15px * var(--fs,1))`, lineHeight: 1.45,
      border: theme.dark ? '1px solid #2c3242' : '1px solid rgba(0,0,0,0.06)',
      boxShadow: theme.dark
        ? '0 40px 90px rgba(0,0,0,0.45), 0 0 0 11px #05070b, 0 0 0 12px #21262f'
        : '0 40px 90px rgba(30,40,60,0.22), 0 0 0 11px #c9cfd6, 0 0 0 12px #aeb6bf',
      display: 'flex', flexDirection: 'column',
    }}>
      <StatusBar tint={t.navTint} />
      <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', position: 'relative' }}>
        {children}
      </div>
      <div style={{ height: 22, flexShrink: 0, display: 'flex', alignItems: 'flex-start', justifyContent: 'center', paddingTop: 6 }}>
        <div style={{ width: 128, height: 5, borderRadius: 99, background: t.navTint, opacity: 0.32 }} />
      </div>
    </div>
  );
}

// ── Buttons ───────────────────────────────────────────────────
function Button({ variant = 'filled', size = 'lg', children, onClick, disabled, leading, full = true, style }) {
  const pads = size === 'lg' ? '0 26px' : '0 18px';
  const h = size === 'lg' ? 56 : 44;
  const fs = size === 'lg' ? 17 : 15;
  const base = {
    height: h, padding: pads, border: 'none', borderRadius: 99, cursor: disabled ? 'default' : 'pointer',
    fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: `calc(${fs}px * var(--fs,1))`,
    letterSpacing: 0.1, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 9,
    width: full ? '100%' : 'auto', opacity: disabled ? 0.38 : 1, whiteSpace: 'nowrap',
  };
  const styles = {
    filled:   { background: 'var(--primary)', color: 'var(--on-primary)', boxShadow: 'var(--shadow-soft)' },
    tonal:    { background: 'var(--primary-container)', color: 'var(--on-primary-container)' },
    outlined: { background: 'transparent', color: 'var(--primary)', boxShadow: 'inset 0 0 0 1.5px var(--outline)' },
    text:     { background: 'transparent', color: 'var(--primary)' },
    ghost:    { background: 'var(--surface-variant)', color: 'var(--on-surface)' },
  }[variant];
  return (
    <button className="ta-press" disabled={disabled} onClick={onClick} style={{ ...base, ...styles, ...style }}>
      {leading}{children}
    </button>
  );
}

function IconButton({ children, onClick, size = 44, variant = 'plain', style, title }) {
  const bg = { plain: 'transparent', tonal: 'var(--surface-variant)', filled: 'var(--primary)' }[variant];
  const col = variant === 'filled' ? 'var(--on-primary)' : 'var(--on-surface)';
  return (
    <button className="ta-press" onClick={onClick} title={title} style={{
      width: size, height: size, borderRadius: 99, border: 'none', background: bg, color: col,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', ...style }}>
      {children}
    </button>
  );
}

// ── Segmented buttons (M3) ────────────────────────────────────
function Segmented({ options, value, onChange, style }) {
  return (
    <div style={{ display: 'flex', background: 'var(--surface-variant)', borderRadius: 99, padding: 4, gap: 4, ...style }}>
      {options.map((o) => {
        const active = o.value === value;
        return (
          <button key={o.value} className="ta-press" onClick={() => onChange(o.value)} style={{
            flex: 1, height: 42, border: 'none', borderRadius: 99, cursor: 'pointer',
            background: active ? 'var(--surface)' : 'transparent',
            color: active ? 'var(--primary)' : 'var(--on-surface-var)',
            boxShadow: active ? 'var(--shadow-soft)' : 'none',
            fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 'calc(14px * var(--fs,1))',
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}>
            {o.icon}{o.label}
          </button>
        );
      })}
    </div>
  );
}

// ── Chip ──────────────────────────────────────────────────────
function Chip({ children, active, onClick, style }) {
  return (
    <button className="ta-press" onClick={onClick} style={{
      height: 40, padding: '0 18px', borderRadius: 99, cursor: 'pointer',
      border: active ? 'none' : '1.5px solid var(--outline)',
      background: active ? 'var(--primary)' : 'transparent',
      color: active ? 'var(--on-primary)' : 'var(--on-surface)',
      fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 'calc(14.5px * var(--fs,1))',
      display: 'inline-flex', alignItems: 'center', gap: 6, ...style }}>
      {children}
    </button>
  );
}

// ── Slider (custom, pointer-draggable) ────────────────────────
function Slider({ value, min = 0, max = 30, step = 1, onChange }) {
  const ref = React.useRef(null);
  const drag = React.useRef(false);
  const pct = (value - min) / (max - min);

  const setFromX = React.useCallback((clientX) => {
    const el = ref.current; if (!el) return;
    const r = el.getBoundingClientRect();
    let p = (clientX - r.left) / r.width;
    p = Math.max(0, Math.min(1, p));
    let v = min + p * (max - min);
    v = Math.round(v / step) * step;
    onChange(Math.max(min, Math.min(max, v)));
  }, [min, max, step, onChange]);

  React.useEffect(() => {
    const move = (e) => { if (drag.current) setFromX(e.touches ? e.touches[0].clientX : e.clientX); };
    const up = () => { drag.current = false; };
    window.addEventListener('pointermove', move);
    window.addEventListener('pointerup', up);
    return () => { window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };
  }, [setFromX]);

  return (
    <div ref={ref} className="ta-press"
      onPointerDown={(e) => { drag.current = true; setFromX(e.clientX); }}
      style={{ position: 'relative', height: 40, display: 'flex', alignItems: 'center', cursor: 'pointer', touchAction: 'none' }}>
      <div style={{ position: 'absolute', left: 0, right: 0, height: 14, borderRadius: 99, background: 'var(--surface-variant)' }} />
      <div style={{ position: 'absolute', left: 0, width: `calc(${pct * 100}% - 6px)`, height: 14, borderRadius: 99, background: 'var(--primary)' }} />
      <div style={{ position: 'absolute', left: `calc(${pct * 100}% - 5px)`, width: 5, height: 28, borderRadius: 99,
        background: 'var(--surface)', boxShadow: '0 0 0 1px var(--outline-faint)' }} />
      <div style={{ position: 'absolute', left: `calc(${pct * 100}% - 14px)`, width: 28, height: 28, borderRadius: 99,
        background: 'var(--surface)', boxShadow: 'var(--shadow), 0 0 0 2px var(--primary)' }} />
    </div>
  );
}

// ── Stepper ───────────────────────────────────────────────────
function Stepper({ value, min = 1, max = 50, onChange }) {
  const btn = (label, fn, dis) => (
    <button className="ta-press" disabled={dis} onClick={fn} style={{
      width: 52, height: 52, borderRadius: 99, border: '1.5px solid var(--outline)', background: 'var(--surface)',
      color: 'var(--on-surface)', cursor: dis ? 'default' : 'pointer', opacity: dis ? 0.35 : 1,
      display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{label}</button>
  );
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 18 }}>
      {btn(<IconMinus s={22} />, () => onChange(Math.max(min, value - 1)), value <= min)}
      <div className="ta-num" style={{ minWidth: 48, textAlign: 'center', fontFamily: 'var(--font-display)',
        fontWeight: 'var(--num-weight)', fontSize: 'calc(34px * var(--fs,1))' }}>{value}</div>
      {btn(<IconPlus s={22} />, () => onChange(Math.min(max, value + 1)), value >= max)}
    </div>
  );
}

// ── Avatar ────────────────────────────────────────────────────
function Avatar({ person, size = 40, ring, dim }) {
  return (
    <div style={{ width: size, height: size, borderRadius: 99, background: person.color, color: '#fff',
      display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: size * 0.4,
      opacity: dim ? 0.32 : 1, boxShadow: ring ? '0 0 0 2.5px var(--surface), 0 0 0 5px var(--primary)' : 'none',
      transition: 'opacity .15s' }}>
      {initials(person.name)}
    </div>
  );
}

// ── Card ──────────────────────────────────────────────────────
function Card({ children, style, onClick, pad = 18, soft }) {
  return (
    <div className={onClick ? 'ta-press' : ''} onClick={onClick} style={{
      background: 'var(--surface)', borderRadius: 'var(--radius)', padding: pad,
      boxShadow: soft ? 'var(--shadow-soft)' : 'var(--shadow)', cursor: onClick ? 'pointer' : 'default', ...style }}>
      {children}
    </div>
  );
}

// ── Big money display ─────────────────────────────────────────
function MoneyBig({ cents, currency, size = 64, color = 'var(--on-surface)', weight }) {
  const txt = fmt(cents, currency, { noSymbol: true });
  const sym = curMeta(currency).symbol;
  return (
    <div className="ta-num" style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'center',
      color, fontFamily: 'var(--font-display)', fontWeight: weight || 'var(--num-weight)', lineHeight: 1 }}>
      <span style={{ fontSize: size * 0.46, marginTop: size * 0.1, marginRight: 2, opacity: 0.7 }}>{sym}</span>
      <span style={{ fontSize: `calc(${size}px * var(--fs,1))`, letterSpacing: -1.5 }}>{txt}</span>
    </div>
  );
}

// ── Toast ─────────────────────────────────────────────────────
function Toast({ toast }) {
  if (!toast) return null;
  return (
    <div style={{ position: 'absolute', left: 16, right: 16, bottom: 20, zIndex: 60, display: 'flex', justifyContent: 'center', pointerEvents: 'none' }}>
      <div className="ta-toast-in" style={{ background: 'var(--on-surface)', color: 'var(--surface)',
        padding: '13px 20px', borderRadius: 99, fontSize: 14, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 9,
        boxShadow: '0 12px 32px rgba(0,0,0,0.3)', maxWidth: '95%' }}>
        {toast.icon}{toast.msg}
      </div>
    </div>
  );
}

// ── Bottom sheet ──────────────────────────────────────────────
function Sheet({ open, onClose, children, title }) {
  if (!open) return null;
  return (
    <div onClick={onClose} style={{ position: 'absolute', inset: 0, zIndex: 50, display: 'flex', alignItems: 'flex-end',
      background: 'rgba(8,10,16,0.42)', backdropFilter: 'blur(2px)' }}>
      <div className="ta-sheet-in" onClick={(e) => e.stopPropagation()} style={{ width: '100%', background: 'var(--surface)',
        borderTopLeftRadius: 30, borderTopRightRadius: 30, padding: '12px 18px 22px', boxShadow: '0 -10px 40px rgba(0,0,0,0.2)' }}>
        <div style={{ width: 38, height: 4, borderRadius: 99, background: 'var(--outline)', margin: '0 auto 14px' }} />
        {title && <div style={{ fontFamily: 'var(--font-display)', fontWeight: 'var(--display-weight)', fontSize: 21, marginBottom: 14, padding: '0 4px' }}>{title}</div>}
        {children}
      </div>
    </div>
  );
}

// ── Section label ─────────────────────────────────────────────
function Label({ children, style }) {
  return <div style={{ fontSize: 'calc(12.5px * var(--fs,1))', fontWeight: 700, letterSpacing: 0.6,
    textTransform: 'uppercase', color: 'var(--on-surface-var)', ...style }}>{children}</div>;
}

Object.assign(window, {
  PhoneShell, StatusBar, Button, IconButton, Segmented, Chip, Slider, Stepper,
  Avatar, Card, MoneyBig, Toast, Sheet, Label,
});
