// ReturnScribe — Shared UI components
// All consume RSTokens via a `t` (theme) prop = RSTokens.dark or RSTokens.light.

const { useState, useEffect, useRef, useMemo } = React;

// ─────────────────────────────────────────────────────────────
// SF-Symbols-ish glyphs (hand-tuned, monoline)
// ─────────────────────────────────────────────────────────────
function Icon({ name, size = 22, color = 'currentColor', weight = 1.8 }) {
  const s = { width: size, height: size, display: 'inline-block', flexShrink: 0 };
  const sw = weight;
  const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth: sw, strokeLinecap: 'round', strokeLinejoin: 'round', style: s };
  switch (name) {
    case 'house':
      return <svg {...props}><path d="M3 11L12 3l9 8"/><path d="M5 10v10h14V10"/></svg>;
    case 'house.fill':
      return <svg {...props} fill={color} stroke="none"><path d="M3 11.5 12 3.2l9 8.3V20a1.5 1.5 0 0 1-1.5 1.5H14V14h-4v7.5H4.5A1.5 1.5 0 0 1 3 20V11.5Z"/></svg>;
    case 'tray':
      return <svg {...props}><path d="M3 13h5l1.5 2h5L16 13h5"/><path d="M3 13V7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6"/><path d="M3 13v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5"/></svg>;
    case 'tray.fill':
      // outline geometry with the lower tray filled — same silhouette, just "inked in"
      return <svg {...props}>
        <path fill={color} stroke="none" d="M3 13h5l1.5 2h5l1.5-2h5v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5Z"/>
        <path d="M3 13V7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6"/>
      </svg>;
    case 'arrow.triangle.2':
      return <svg {...props}><path d="M7 4 4 7l3 3"/><path d="M4 7h12a4 4 0 0 1 4 4"/><path d="M17 20l3-3-3-3"/><path d="M20 17H8a4 4 0 0 1-4-4"/></svg>;
    case 'arrow.triangle.2.fill':
      // same glyph as outline, heavier weight — the cycle arrows have no good solid form
      return <svg {...props} strokeWidth={2.6}><path d="M7 4 4 7l3 3"/><path d="M4 7h12a4 4 0 0 1 4 4"/><path d="M17 20l3-3-3-3"/><path d="M20 17H8a4 4 0 0 1-4-4"/></svg>;
    case 'creditcard':
      return <svg {...props}><rect x="2" y="5.5" width="20" height="13" rx="2.4"/><path d="M2 10h20"/><path d="M6 15h4"/></svg>;
    case 'creditcard.fill':
      return <svg {...props} fill={color} stroke="none"><path d="M2 7.5A2.5 2.5 0 0 1 4.5 5h15A2.5 2.5 0 0 1 22 7.5V9H2V7.5Zm0 4h20v5A2.5 2.5 0 0 1 19.5 19h-15A2.5 2.5 0 0 1 2 16.5v-5Zm4 4.5h4v-1.5H6V16Z"/></svg>;
    case 'wallet':
      return <svg {...props}><rect x="2.5" y="5.5" width="19" height="14" rx="2.6"/><path d="M16 12.5h3"/><path d="M2.5 9h19"/></svg>;
    case 'wallet.fill':
      return <svg {...props} fill={color} stroke="none"><path d="M4.5 4h13C19 4 20 5 20 6.5V8H4.5C3 8 2 9 2 10.5v6A2.5 2.5 0 0 0 4.5 19h15A2.5 2.5 0 0 0 22 16.5v-6c0-1.2-.8-2.2-1.9-2.4V6.5C20.1 4.6 18.5 3 16.6 3H4.5C3 3 2 4 2 5.5 2 4.7 2.7 4 4.5 4Zm12 9.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"/></svg>;
    case 'gear':
      return <svg {...props}><circle cx="12" cy="12" r="2.7"/><path d="M19.4 13.5a7.6 7.6 0 0 0 0-3l2-1.5-2-3.5-2.4.8a7.6 7.6 0 0 0-2.6-1.5L13.5 2h-3l-.9 2.8A7.6 7.6 0 0 0 7 6.3l-2.4-.8-2 3.5 2 1.5a7.6 7.6 0 0 0 0 3l-2 1.5 2 3.5 2.4-.8a7.6 7.6 0 0 0 2.6 1.5l.9 2.8h3l.9-2.8a7.6 7.6 0 0 0 2.6-1.5l2.4.8 2-3.5-2-1.5Z"/></svg>;
    case 'gear.fill':
      // outline gear at heavier weight with a solid hub — keeps the exact tooth silhouette
      return <svg {...props} strokeWidth={2.2}><circle cx="12" cy="12" r="2.7" fill={color} stroke="none"/><path d="M19.4 13.5a7.6 7.6 0 0 0 0-3l2-1.5-2-3.5-2.4.8a7.6 7.6 0 0 0-2.6-1.5L13.5 2h-3l-.9 2.8A7.6 7.6 0 0 0 7 6.3l-2.4-.8-2 3.5 2 1.5a7.6 7.6 0 0 0 0 3l-2 1.5 2 3.5 2.4-.8a7.6 7.6 0 0 0 2.6 1.5l.9 2.8h3l.9-2.8a7.6 7.6 0 0 0 2.6-1.5l2.4.8 2-3.5-2-1.5Z"/></svg>;
    case 'chevron.right':
      return <svg {...props}><path d="M9 5l7 7-7 7"/></svg>;
    case 'chevron.left':
      return <svg {...props}><path d="M15 5l-7 7 7 7"/></svg>;
    case 'chevron.down':
      return <svg {...props}><path d="M5 9l7 7 7-7"/></svg>;
    case 'plus':
      return <svg {...props}><path d="M12 5v14M5 12h14"/></svg>;
    case 'sun':
      return <svg {...props}><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>;
    case 'moon':
      return <svg {...props}><path d="M20 14.5A8 8 0 1 1 9.5 4a6.5 6.5 0 0 0 10.5 10.5Z"/></svg>;
    case 'magnifyingglass':
      return <svg {...props}><circle cx="11" cy="11" r="6.5"/><path d="m16 16 4 4"/></svg>;
    case 'ellipsis':
      return <svg {...props} fill={color} stroke="none"><circle cx="5" cy="12" r="1.6"/><circle cx="12" cy="12" r="1.6"/><circle cx="19" cy="12" r="1.6"/></svg>;
    case 'clock':
      return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3.2 2"/></svg>;
    case 'bell':
      return <svg {...props}><path d="M6 9a6 6 0 1 1 12 0c0 6 2 7 2 7H4s2-1 2-7Z"/><path d="M10 20a2 2 0 0 0 4 0"/></svg>;
    case 'calendar':
      return <svg {...props}><rect x="3" y="5" width="18" height="16" rx="2.5"/><path d="M3 10h18M8 3v4M16 3v4"/></svg>;
    case 'envelope':
      return <svg {...props}><rect x="2.5" y="5" width="19" height="14" rx="2.5"/><path d="m3 7 9 6 9-6"/></svg>;
    case 'lock':
      return <svg {...props}><rect x="4" y="11" width="16" height="10" rx="2.4"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></svg>;
    case 'shield':
      return <svg {...props}><path d="M12 3l8 3v5c0 5-3.5 9-8 10-4.5-1-8-5-8-10V6l8-3Z"/></svg>;
    case 'doc':
      return <svg {...props}><path d="M6 3h9l4 4v14a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Z"/><path d="M14 3v5h5"/></svg>;
    case 'qrcode':
      return <svg {...props}><rect x="3.5" y="3.5" width="6" height="6" rx="1"/><rect x="14.5" y="3.5" width="6" height="6" rx="1"/><rect x="3.5" y="14.5" width="6" height="6" rx="1"/><path d="M14 14.5v3M17 14.5v6M20.5 14.5v3M14.5 17.5h3M14.5 20.5h6M17.5 17.5v3"/></svg>;
    case 'sparkles':
      return <svg {...props} fill={color} stroke="none"><path d="M12 2.5l1.7 5 5 1.7-5 1.7-1.7 5-1.7-5-5-1.7 5-1.7 1.7-5Z"/><path d="M18.5 13l.85 2.4 2.4.85-2.4.85-.85 2.4-.85-2.4-2.4-.85 2.4-.85.85-2.4Z" opacity="0.85"/><path d="M5 14l.6 1.7 1.7.6-1.7.6L5 18.6l-.6-1.7-1.7-.6 1.7-.6L5 14Z" opacity="0.7"/></svg>;
    case 'arrow.up.right':
      return <svg {...props}><path d="M7 17 17 7M9 7h8v8"/></svg>;
    case 'arrow.down.left':
      return <svg {...props}><path d="M17 7 7 17M15 17H7V9"/></svg>;
    case 'check':
      return <svg {...props}><path d="m5 12 5 5 9-11"/></svg>;
    case 'xmark':
      return <svg {...props}><path d="M6 6l12 12M18 6 6 18"/></svg>;
    case 'paperplane':
      return <svg {...props}><path d="M21 3 3 10l7 3 3 7 8-17Z"/><path d="m10 13 5-5"/></svg>;
    case 'tag':
      return <svg {...props}><path d="M3 12V4a1 1 0 0 1 1-1h8l9 9-9 9-9-9Z"/><circle cx="8" cy="8" r="1.4"/></svg>;
    case 'bag':
      return <svg {...props}><path d="M5 8h14l-1 12.2a1.5 1.5 0 0 1-1.5 1.3h-9A1.5 1.5 0 0 1 6 20.2L5 8Z"/><path d="M8.5 8V6a3.5 3.5 0 1 1 7 0v2"/></svg>;
    case 'flame':
      return <svg {...props}><path d="M12 3s5 5 5 10a5 5 0 1 1-10 0c0-2 1-3 2-4-1 4 2 4 2 2 0-3 1-5 1-8Z"/></svg>;
    case 'play':
      return <svg {...props} fill={color}><path d="M7 4.5v15l13-7.5-13-7.5Z"/></svg>;
    case 'pause':
      return <svg {...props} fill={color} stroke="none"><rect x="6" y="4.5" width="4" height="15" rx="1"/><rect x="14" y="4.5" width="4" height="15" rx="1"/></svg>;
    case 'sliders':
      return <svg {...props}><path d="M4 6h11M4 12h6M4 18h13"/><circle cx="18" cy="6" r="2"/><circle cx="13" cy="12" r="2"/><circle cx="20" cy="18" r="2"/></svg>;
    default:
      return <svg {...props}><rect x="3" y="3" width="18" height="18" rx="3"/></svg>;
  }
}

// ─────────────────────────────────────────────────────────────
// Currency formatter — keeps tabular-nums + decimal
// ─────────────────────────────────────────────────────────────
function Money({ value, size = 56, color, weight = 600, dim = 0.42 }) {
  const sign = value < 0 ? '−' : '';
  const abs = Math.abs(value);
  const whole = Math.floor(abs).toLocaleString('en-US');
  const frac = abs.toFixed(2).split('.')[1];
  return (
    <span style={{
      fontFamily: RSFont.num, fontWeight: weight, color,
      fontSize: size, lineHeight: 1.02, letterSpacing: '-0.04em',
      ...RSTabular,
      whiteSpace: 'nowrap',
    }}>
      <span style={{ opacity: 0.55, fontSize: '0.55em', verticalAlign: '0.32em', marginRight: 1 }}>$</span>
      {sign}{whole}
      <span style={{ opacity: dim, fontSize: '0.55em', verticalAlign: '0.32em' }}>.{frac}</span>
    </span>
  );
}

// ─────────────────────────────────────────────────────────────
// Status badge — typographic, foreground-only
// ─────────────────────────────────────────────────────────────
function StatusBadge({ label, color }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center',
      ...applyMono(RSType.badge),
      textTransform: 'uppercase',
      color, whiteSpace: 'nowrap',
      border: `1px solid ${color}55`,
      borderRadius: 3, padding: '2px 6px',
    }}>{label}</span>
  );
}

// ─────────────────────────────────────────────────────────────
// Merchant mark — uppercase initial(s), no logos (placeholder pattern)
// ─────────────────────────────────────────────────────────────
const merchantPalette = [
  ['#3A3F4B', '#E8E9EC'], ['#2A3F2E', '#D4E5D6'], ['#3B2F1F', '#E8D9BB'],
  ['#3A2A3F', '#E2D0E8'], ['#2A3A3F', '#CFE0E5'], ['#3F2A2A', '#F0CFCC'],
  ['#2D2D32', '#FF8C42'], ['#1F2A3A', '#B7D2EE'],
];
function MerchantMark({ name, size = 40, square = true }) {
  const initials = name.split(/[\s.]+/).slice(0, 2).map(s => s[0]).join('').toUpperCase();
  const idx = name.charCodeAt(0) % merchantPalette.length;
  const [bg, fg] = merchantPalette[idx];
  return (
    <div style={{
      width: size, height: size, borderRadius: square ? Math.round(size * 0.28) : 9999,
      background: bg, color: fg,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: RSFont.sys, fontSize: Math.round(size * 0.42), fontWeight: 600,
      letterSpacing: 0.3, flexShrink: 0,
    }}>{initials}</div>
  );
}

// ─────────────────────────────────────────────────────────────
// MerchantLogo — premium upgrade: real logos via Clearbit CDN
// with graceful fallback to a tinted icon avatar.
// Mirrors the production MerchantAvatar.tsx from ReturnScribe.
// ─────────────────────────────────────────────────────────────
const MERCHANT_DOMAINS = {
  amazon: 'amazon.com', adobe: 'adobe.com', hulu: 'hulu.com',
  netflix: 'netflix.com', spotify: 'spotify.com', nordstrom: 'nordstrom.com',
  target: 'target.com', apple: 'apple.com', google: 'google.com',
  microsoft: 'microsoft.com', samsung: 'samsung.com', walmart: 'walmart.com',
  bestbuy: 'bestbuy.com', 'best buy': 'bestbuy.com',
  nike: 'nike.com', adidas: 'adidas.com', costco: 'costco.com',
  homedepot: 'homedepot.com', 'home depot': 'homedepot.com',
  lowes: 'lowes.com', wayfair: 'wayfair.com', etsy: 'etsy.com',
  ebay: 'ebay.com', chewy: 'chewy.com', uniqlo: 'uniqlo.com',
  zara: 'zara.com', sephora: 'sephora.com', ulta: 'ulta.com',
  ikea: 'ikea.com', lululemon: 'lululemon.com', patagonia: 'patagonia.com',
  paypal: 'paypal.com', uber: 'uber.com', doordash: 'doordash.com',
  rei: 'rei.com', 'crate': 'crateandbarrel.com',
  notion: 'notion.so', dropbox: 'dropbox.com', figma: 'figma.com',
  disney: 'disneyplus.com', hbo: 'hbo.com', youtube: 'youtube.com',
};
const AVATAR_COLORS = ['#3D6B9E','#7A5CA8','#96690F','#3E8F7C','#C2451E','#A8527B','#3A7D3E','#5B8A8F'];
function _merchantColor(name) {
  let h = 0;
  for (let i = 0; i < name.length; i++) h = name.charCodeAt(i) + ((h << 5) - h);
  return AVATAR_COLORS[Math.abs(h) % AVATAR_COLORS.length];
}
function _merchantDomain(name) {
  const k = name.toLowerCase().trim();
  for (const [key, d] of Object.entries(MERCHANT_DOMAINS)) {
    if (k.includes(key) || key.includes(k)) return d;
  }
  return null;
}
function MerchantLogo({ name, size = 44, t, cat }) {
  const [failed, setFailed] = useState(false);
  const domain = _merchantDomain(name);
  const mc = _merchantColor(name);
  const radius = Math.round(size * 0.28);
  // Real logos via Clearbit are opt-in (window.RS_LOGOS = true). Off by default
  // so offline/preview environments fall back to the tinted category avatar.
  const useLogos = typeof window !== 'undefined' && window.RS_LOGOS === true;

  if (!useLogos || !domain || failed) {
    // Industry-icon fallback — ruled stamp box
    const iconSize = Math.round(size * 0.5);
    return (
      <div style={{
        width: size, height: size, borderRadius: Math.max(6, size * 0.14),
        background: mc + '14',
        border: `1px solid ${mc}40`,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0,
      }}>
        {cat
          ? <CategoryIcon symbol={cat} size={iconSize} color={mc}/>
          : <Icon name="bag" size={iconSize} color={mc}/>}
      </div>
    );
  }

  return (
    <div style={{
      width: size, height: size, borderRadius: radius,
      background: '#FFFFFF',
      border: `0.5px solid ${(t && t.border) || 'rgba(0,0,0,0.08)'}`,
      padding: Math.round(size * 0.12),
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0, overflow: 'hidden',
      boxShadow: '0 1px 2px rgba(0,0,0,0.04)',
    }}>
      <img
        src={`https://logo.clearbit.com/${domain}?size=${size * 2}`}
        alt={name}
        onError={() => setFailed(true)}
        style={{ width: '100%', height: '100%', objectFit: 'contain', display: 'block' }}
      />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// AuroraBlobs — animated multi-color gradient hero background
// Mirrors AuroraBackground.tsx (4 blobs, brand palette, slow drift)
// ─────────────────────────────────────────────────────────────
function AuroraBlobs({ height = 220, opacity = 1 }) {
  const blobs = [
    { color: RSBrand.blue,   size: 260, left: -60, top: -60, ax:  40, ay:  30, dur: '7.2s', delay: '0s',   op: 0.42 },
    { color: RSBrand.teal,   size: 220, left: 180, top: -30, ax: -30, ay:  40, dur: '8.8s', delay: '0.9s', op: 0.34 },
    { color: RSBrand.purple, size: 200, left:  40, top: 110, ax:  25, ay: -35, dur: '6.4s', delay: '0.4s', op: 0.28 },
    { color: RSBrand.orange, size: 160, left: 240, top: 110, ax: -40, ay:  20, dur: '9.2s', delay: '1.6s', op: 0.22 },
  ];
  return (
    <div style={{
      position: 'absolute', inset: 0, height, overflow: 'hidden',
      pointerEvents: 'none', opacity, filter: 'blur(2px)',
    }}>
      {blobs.map((b, i) => (
        <div key={i} style={{
          position: 'absolute',
          left: b.left, top: b.top,
          width: b.size, height: b.size, borderRadius: '50%',
          background: b.color, opacity: b.op,
          filter: 'blur(34px)',
          ['--ax']: b.ax + 'px', ['--ay']: b.ay + 'px',
          animation: `rsAuroraDrift ${b.dur} ease-in-out ${b.delay} infinite`,
          willChange: 'transform',
        }}/>
      ))}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// SectionTitle — pip dot + label + colored count chip
// Mirrors the ReturnScribe section headers
// ─────────────────────────────────────────────────────────────
function SectionTitle({ t, label, count, color, action }) {
  const c = color || t.accent;
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      padding: '20px 20px 10px',
    }}>
      <span style={{ color: t.text2, ...applyMono(RSType.eyebrow), textTransform: 'uppercase', flexShrink: 0, whiteSpace: 'nowrap' }}>{label}</span>
      <span style={{ flex: 1, height: 1, background: t.border }}></span>
      {count != null && (
        <span style={{
          color: c, ...applyMono(RSType.caption), fontWeight: 600,
          border: `1px solid ${c}55`, borderRadius: 3, padding: '1px 7px',
        }}>{count}</span>
      )}
      {action}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Card — surface 1 + optional border
// ─────────────────────────────────────────────────────────────
function Card({ t, children, style = {}, padding = 20, radius = 10, surface = 1, border = true }) {
  const isDark = t === RSTokens.dark;
  return (
    <div style={{
      background: surface === 2 ? t.surface2 : t.surface1,
      borderRadius: radius, padding,
      border: border ? `1px solid ${t.borderStrong}` : 'none',
      boxShadow: border
        ? (isDark ? '0 2px 0 rgba(0,0,0,0.28)' : `2px 2px 0 ${t.border}`)
        : 'none',
      ...style,
    }}>{children}</div>
  );
}

// ─────────────────────────────────────────────────────────────
// Glass surface (for tab bar / hero / nav toolbar only — accent moments)
// ─────────────────────────────────────────────────────────────
// Paper panel — translucent paper with blur (dock, sticky footers)
function Glass({ t, children, style = {}, radius = 14, padding = 20, intensity, sheen }) {
  return (
    <div style={{
      position: 'relative', borderRadius: radius, padding,
      background: t.glassBg,
      backdropFilter: 'blur(16px) saturate(120%)',
      WebkitBackdropFilter: 'blur(16px) saturate(120%)',
      border: `1px solid ${t.borderStrong}`,
      boxShadow: t === RSTokens.dark
        ? '0 10px 30px rgba(0,0,0,0.4)'
        : `3px 3px 0 ${t.border}`,
      isolation: 'isolate',
      ...style,
    }}>
      <div style={{ position: 'relative', display: 'contents' }}>{children}</div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Primary / Secondary / Text buttons
// ─────────────────────────────────────────────────────────────
function Button({ t, kind = 'primary', children, full = true, icon, onClick, style = {} }) {
  const base = {
    height: 52, borderRadius: 8, border: 'none', padding: '0 20px',
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
    width: full ? '100%' : undefined, cursor: 'pointer',
    ...applyMono(RSType.subhead, { fontWeight: 600, textTransform: 'uppercase', letterSpacing: '1.2px', fontSize: 13 }),
  };
  const variants = {
    primary: {
      background: t.accent, color: t === RSTokens.dark ? '#1A130F' : '#FBF8F1',
      boxShadow: t === RSTokens.dark ? '0 2px 0 rgba(0,0,0,0.35)' : `2px 2px 0 ${t.borderStrong}`,
    },
    secondary: {
      background: 'transparent', color: t.accent,
      boxShadow: `inset 0 0 0 1.5px ${t.accent}`,
    },
    destructive: { background: 'transparent', color: t.danger, height: 44 },
    text: { background: 'transparent', color: t.accent, height: 'auto', padding: 0 },
  };
  return (
    <button onClick={onClick} style={{ ...base, ...variants[kind], ...style }}>
      {icon}{children}
    </button>
  );
}

// ─────────────────────────────────────────────────────────────
// Large nav title block (for non-glass-toolbar screens)
// ─────────────────────────────────────────────────────────────
function NavTitle({ t, title, trailing, leading, subtitle, paddingTop = 8 }) {
  return (
    <div style={{ padding: `${paddingTop}px 20px 12px`, display: 'flex', flexDirection: 'column', gap: 4 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: 32 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>{leading}</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>{trailing}</div>
      </div>
      <h1 style={{
        margin: 0, color: t.text1, ...applyDisp(RSType.large),
      }}>{title}</h1>
      {subtitle && <div style={{ color: t.text2, ...applyType(RSType.subhead) }}>{subtitle}</div>}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Tab bar — glass material, 6 tabs, with active indicator pill
// ─────────────────────────────────────────────────────────────
const TABS = [
  { id: 'home',     label: 'Home',     icon: 'house' },
  { id: 'inbox',    label: 'Inbox',    icon: 'tray' },
  { id: 'subs',     label: 'Subs',     icon: 'arrow.triangle.2' },
  { id: 'refunds',  label: 'Refunds',  icon: 'creditcard' },
  { id: 'settings', label: 'Settings', icon: 'gear' },
];

function TabBar({ t, active = 'home', onChange }) {
  const dark = t === RSTokens.dark;
  return (
    <div style={{
      position: 'absolute', left: 10, right: 10, bottom: 12, zIndex: 30,
    }}>
      <div style={{
        height: 64, borderRadius: 32, position: 'relative',
        display: 'flex', alignItems: 'center', justifyContent: 'space-around',
        padding: '0 6px', overflow: 'hidden',
        // liquid glass: heavy blur + low-opacity tint so content flows beneath
        background: dark ? 'rgba(30,31,34,0.38)' : 'rgba(252,251,248,0.42)',
        backdropFilter: 'blur(36px) saturate(190%)',
        WebkitBackdropFilter: 'blur(36px) saturate(190%)',
        border: dark ? '0.5px solid rgba(255,255,255,0.14)' : '0.5px solid rgba(0,0,0,0.07)',
        boxShadow: dark
          ? 'inset 1.5px 1.5px 1px rgba(255,255,255,0.14), inset -1px -1px 1px rgba(255,255,255,0.06), 0 8px 32px rgba(0,0,0,0.45)'
          : 'inset 1.5px 1.5px 1px rgba(255,255,255,0.85), inset -1px -1px 1px rgba(255,255,255,0.45), 0 6px 24px rgba(0,0,0,0.10)',
      }}>
        {/* top specular streak */}
        <div style={{
          position: 'absolute', top: 0, left: '8%', right: '8%', height: 1,
          background: dark
            ? 'linear-gradient(90deg, transparent, rgba(255,255,255,0.35), transparent)'
            : 'linear-gradient(90deg, transparent, rgba(255,255,255,0.95), transparent)',
          pointerEvents: 'none',
        }}></div>
        {TABS.map(tab => {
          const isActive = tab.id === active;
          const c = isActive ? t.accent : t.text2;
          return (
            <button key={tab.id} onClick={() => onChange && onChange(tab.id)}
              style={{
                background: 'none', border: 'none', cursor: 'pointer',
                display: 'flex', flexDirection: 'column', alignItems: 'center',
                justifyContent: 'center', gap: 2,
                height: 52, minWidth: 58, borderRadius: 26, position: 'relative',
              }}>
              {/* active lens — small glass pill behind the active tab */}
              {isActive && (
                <span style={{
                  position: 'absolute', inset: 0, borderRadius: 26,
                  background: dark ? 'rgba(255,255,255,0.10)' : 'rgba(255,255,255,0.65)',
                  border: dark ? '0.5px solid rgba(255,255,255,0.16)' : '0.5px solid rgba(0,0,0,0.05)',
                  boxShadow: dark
                    ? 'inset 1px 1px 0.5px rgba(255,255,255,0.18), 0 2px 8px rgba(0,0,0,0.25)'
                    : 'inset 1px 1px 0.5px rgba(255,255,255,0.9), 0 2px 8px rgba(0,0,0,0.07)',
                  pointerEvents: 'none',
                }}></span>
              )}
              <span style={{ position: 'relative', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2 }}>
                <Icon name={isActive ? tab.icon + '.fill' : tab.icon} size={24} color={c} weight={1.8}/>
                <span style={{
                  fontFamily: RSFont.sys, fontSize: 10, fontWeight: 600,
                  color: c, letterSpacing: 0.1,
                }}>{tab.label}</span>
              </span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Status-bar overlay (light/dark) + home indicator (managed by ios frame)
// We use a stripped-down version inside our own device shell since we want
// full content control + theme-driven status bar tinting.
// ─────────────────────────────────────────────────────────────
function StatusBar({ dark, time = '9:41' }) {
  const c = dark ? '#fff' : '#000';
  // time + indicators centered within the left/right "ears" beside the island
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '15px 0 8px', fontFamily: RSFont.sys,
    }}>
      <span style={{ width: 136, textAlign: 'center', fontWeight: 600, fontSize: 17, color: c, letterSpacing: -0.2 }}>{time}</span>
      <div style={{ width: 136, display: 'flex', gap: 6, alignItems: 'center', justifyContent: 'center' }}>
        <svg width="18" height="11" viewBox="0 0 18 11"><rect x="0" y="7" width="3" height="4" rx="0.6" fill={c}/><rect x="4.5" y="5" width="3" height="6" rx="0.6" fill={c}/><rect x="9" y="2.5" width="3" height="8.5" rx="0.6" fill={c}/><rect x="13.5" y="0" width="3" height="11" rx="0.6" fill={c}/></svg>
        <svg width="16" height="11" viewBox="0 0 16 11"><path d="M8 3.2C10 3.2 12 4 13.3 5.4l1-1A8 8 0 0 0 8 1.5 8 8 0 0 0 1.7 4.4l1 1C4 4 6 3.2 8 3.2Z" fill={c}/><path d="M8 6.6c1.2 0 2.3.5 3.1 1.3l1-1A6 6 0 0 0 8 5a6 6 0 0 0-4.1 1.9l1 1C5.7 7 6.8 6.6 8 6.6Z" fill={c}/><circle cx="8" cy="9.6" r="1.4" fill={c}/></svg>
        <svg width="25" height="12" viewBox="0 0 25 12"><rect x="0.5" y="0.5" width="21" height="11" rx="3" stroke={c} strokeOpacity="0.4" fill="none"/><rect x="2" y="2" width="17" height="8" rx="1.6" fill={c}/><path d="M23 4v4c.7-.2 1.3-1 1.3-2s-.6-1.8-1.3-2Z" fill={c} fillOpacity="0.4"/></svg>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Device shell — 393×852, themed, with content padding to tab bar
// ─────────────────────────────────────────────────────────────
function Phone({ t, children, dark, hideTab, activeTab, onTabChange, contentRef }) {
  return (
    <div style={{
      width: 393, height: 852, borderRadius: 50, overflow: 'hidden',
      position: 'relative', background: t.canvas,
      boxShadow: '0 30px 60px rgba(0,0,0,0.18), 0 0 0 1px rgba(0,0,0,0.12)',
      fontFamily: RSFont.sys,
      WebkitFontSmoothing: 'antialiased',
      color: t.text1,
    }}>
      {/* dynamic island */}
      <div style={{
        position: 'absolute', top: 11, left: '50%', transform: 'translateX(-50%)',
        width: 120, height: 34, borderRadius: 22, background: '#000', zIndex: 50,
      }} />
      <StatusBar dark={dark}/>
      <div ref={contentRef} style={{
        position: 'absolute', top: 47, left: 0, right: 0, bottom: 0,
        overflow: 'auto', paddingBottom: hideTab ? 24 : 100,
      }}>{children}</div>
      {!hideTab && <TabBar t={t} active={activeTab} onChange={onTabChange}/>}
      {/* home indicator */}
      <div style={{
        position: 'absolute', bottom: 8, left: 0, right: 0, zIndex: 70,
        display: 'flex', justifyContent: 'center', pointerEvents: 'none',
      }}>
        <div style={{
          width: 134, height: 5, borderRadius: 100,
          background: dark ? 'rgba(255,255,255,0.4)' : 'rgba(0,0,0,0.3)',
        }}/>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// List row — generic 56-64pt min, 16pt h-pad
// ─────────────────────────────────────────────────────────────
function ListRow({ t, leading, title, subtitle, trailing, trailingSub, chevron, isLast, onClick, sep = true }) {
  return (
    <div onClick={onClick} style={{
      display: 'flex', alignItems: 'center', gap: 14, padding: '13px 16px', minHeight: 64,
      cursor: onClick ? 'pointer' : 'default', position: 'relative',
    }}>
      {leading}
      <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 3 }}>
        <div style={{ color: t.text1, ...applyType(RSType.headline), whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{title}</div>
        {subtitle && <div style={{ color: t.text2, ...applyType(RSType.footnote), whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{subtitle}</div>}
      </div>
      {trailing && (
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 3 }}>
          <div style={{ color: t.text1, ...applyMono(RSType.headline), fontWeight: 500, ...RSTabular }}>{trailing}</div>
          {trailingSub && <div style={{ color: t.text2, ...applyType(RSType.footnote) }}>{trailingSub}</div>}
        </div>
      )}
      {chevron && <Icon name="chevron.right" size={14} color={t.text3} weight={2.2}/>}
      {!isLast && sep && <div style={{ position: 'absolute', left: leading ? 70 : 16, right: 16, bottom: 0, height: 0.5, background: t.border }}/>}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Section header — small caps subhead
// ─────────────────────────────────────────────────────────────
function SectionHead({ t, title, action }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 20px 8px' }}>
      <span style={{ color: t.text3, ...applyMono(RSType.eyebrow), textTransform: 'uppercase', flexShrink: 0, whiteSpace: 'nowrap' }}>{title}</span>
      <span style={{ flex: 1, height: 1, background: t.border }}></span>
      {action}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Filter pill row
// ─────────────────────────────────────────────────────────────
function FilterPills({ t, items, active, onChange }) {
  return (
    <div style={{
      display: 'flex', gap: 8, padding: '0 20px 12px', overflowX: 'auto',
      WebkitOverflowScrolling: 'touch', scrollbarWidth: 'none',
    }}>
      {items.map(it => {
        const a = it.id === active;
        return (
          <button key={it.id} onClick={() => onChange && onChange(it.id)} style={{
            background: a ? t.accent : t.chip,
            color: a ? '#fff' : t.text1,
            border: 'none', borderRadius: 999, padding: '8px 14px',
            ...applyType(RSType.footnote), fontWeight: 600, cursor: 'pointer',
            whiteSpace: 'nowrap',
          }}>
            {it.label}{it.count != null && <span style={{ opacity: 0.6, marginLeft: 6 }}>{it.count}</span>}
          </button>
        );
      })}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Segmented control (iOS-native)
// ─────────────────────────────────────────────────────────────
function Segmented({ t, items, active, onChange }) {
  return (
    <div style={{
      display: 'flex', padding: 3, borderRadius: 10,
      background: t.surface2, margin: '0 20px',
    }}>
      {items.map(it => {
        const a = it.id === active;
        return (
          <button key={it.id} onClick={() => onChange && onChange(it.id)} style={{
            flex: 1, height: 32, border: 'none', borderRadius: 7,
            background: a ? t.surface1 : 'transparent',
            color: t.text1, cursor: 'pointer',
            ...applyType(RSType.subhead), fontWeight: a ? 600 : 500,
            boxShadow: a ? '0 1px 2px rgba(0,0,0,0.1)' : 'none',
          }}>{it.label}</button>
        );
      })}
    </div>
  );
}

Object.assign(window, {
  Icon, Money, StatusBadge, MerchantMark, MerchantLogo, AuroraBlobs, SectionTitle,
  Card, Glass, Button,
  NavTitle, TabBar, StatusBar, Phone, ListRow, SectionHead,
  FilterPills, Segmented,
});
