// ui.jsx — small shared presentational components

function Stepper({ value, onChange, min = 1, max = 20, step = 1 }) {
  return (
    <div className="stepper">
      <button onClick={() => onChange(Math.max(min, value - step))} aria-label="decrease">
        <Icon name="minus" size={18} sw={2.4} />
      </button>
      <span className="val">{value}</span>
      <button onClick={() => onChange(Math.min(max, value + step))} aria-label="increase">
        <Icon name="plus" size={18} sw={2.4} />
      </button>
    </div>
  );
}

function HypeBadge({ hype }) {
  if (hype === 'chase')  return <span className="badge badge-gold"><Icon name="star" size={11} fill color="var(--gold)" />Chase set</span>;
  if (hype === 'hot')    return <span className="badge badge-accent"><Icon name="flame" size={11} fill color="var(--accent)" />Hot</span>;
  if (hype === 'low')    return <span className="badge badge-low">Low stock</span>;
  return null;
}

function StockMeter({ stock }) {
  const pct = Math.min(100, (stock / 60) * 100);
  const low = stock <= 15;
  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--ff-mono)', fontSize: 11, color: low ? 'var(--gold)' : 'var(--ink-3)', marginBottom: 5 }}>
        <span>{low ? 'LOW STOCK' : 'IN STOCK'}</span>
        <span>{stock} packs</span>
      </div>
      <div style={{ height: 6, borderRadius: 9999, background: 'var(--paper-2)', overflow: 'hidden', boxShadow: 'inset 0 0 0 1px var(--line)' }}>
        <span style={{ display: 'block', height: '100%', width: pct + '%', borderRadius: 9999, background: low ? 'var(--gold)' : 'var(--good)' }} />
      </div>
    </div>
  );
}

// price block: MSRP struck vs our fair price
function PriceTag({ set, markup, size = 'md' }) {
  const fair = fairPrice(set.msrp, markup);
  const big = size === 'lg';
  return (
    <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
      <span style={{ fontFamily: 'var(--ff-display)', fontWeight: 800, fontSize: big ? 30 : 19, color: 'var(--ink)' }}>{money(fair)}</span>
      <span style={{ fontFamily: 'var(--ff-mono)', fontSize: big ? 13 : 11, color: 'var(--ink-3)', textDecoration: 'line-through' }}>MSRP {money(set.msrp)}</span>
    </div>
  );
}

// A header used inside scroll content (not the pushed-screen back header)
// tagline defaults to the pack line; the singles front door overrides it, since
// "Fair packs" is the wrong promise over a shelf of singles.
function BrandBar({ t, onBell, cartCount = 0, onCart, tagline }) {
  return (
    <div style={{ padding: 'var(--top-pad) 20px 8px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{ width: 40, height: 40, borderRadius: 12, background: 'var(--ink)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <RookMark size={24} color="var(--paper)" />
        </div>
        <div style={{ lineHeight: 1 }}>
          <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 800, fontSize: 18, letterSpacing: '-0.02em' }}>{BRAND.short}</div>
          <div className="kicker" style={{ marginTop: 3, fontSize: 10 }}>{tagline || BRAND.place + ' · Fair packs'}</div>
        </div>
      </div>
      <div style={{ display: 'flex', gap: 9 }}>
        {cartCount > 0 && (
          <button onClick={onCart} style={{ width: 40, height: 40, borderRadius: 9999, border: 'none', background: 'var(--surface)', boxShadow: 'var(--shadow-sm)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: 'var(--ink)', position: 'relative' }}>
            <Icon name="cart" size={20} />
            <span style={{ position: 'absolute', top: -3, right: -3, minWidth: 17, height: 17, padding: '0 4px', borderRadius: 9999, background: 'var(--accent)', color: 'var(--on-accent)', fontFamily: 'var(--ff-mono)', fontSize: 9.5, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 0 0 2px var(--surface)' }}>{cartCount}</span>
          </button>
        )}
        <button onClick={onBell} style={{ width: 40, height: 40, borderRadius: 9999, border: 'none', background: 'var(--surface)', boxShadow: 'var(--shadow-sm)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: 'var(--ink)', position: 'relative' }}>
          <Icon name="bell" size={20} />
          <span style={{ position: 'absolute', top: 9, right: 10, width: 7, height: 7, borderRadius: 9999, background: 'var(--accent)', boxShadow: '0 0 0 2px var(--surface)' }} />
        </button>
      </div>
    </div>
  );
}

// The shelves. Live categories are selectable; queued ones stay visible and
// say when they land rather than being hidden until they exist.
function CategoryRail({ activeId = LEAD_CATEGORY.id, onQueued }) {
  return (
    <div className="rail cat-rail">
      {CATEGORIES.map(c => {
        const live = c.status === 'live';
        const on = live && c.id === activeId;
        return (
          <button key={c.id} title={c.blurb} aria-current={on ? 'true' : undefined}
                  className={'cat-chip' + (on ? ' on' : '') + (live ? '' : ' soon')}
                  onClick={live ? undefined : () => onQueued && onQueued(c)}>
            <Icon name={c.icon} size={15} sw={2.2} />
            <span>{c.short}</span>
            {!live && <em>{c.status === 'next' ? 'Next' : 'Soon'}</em>}
          </button>
        );
      })}
    </div>
  );
}

// Push-screen header with back button
function PushHeader({ title, onBack, trailing }) {
  return (
    <div style={{ padding: 'var(--top-pad) 16px 12px', display: 'flex', alignItems: 'center', gap: 12, background: 'var(--paper)', position: 'relative', zIndex: 2 }}>
      <button onClick={onBack} style={{ width: 40, height: 40, borderRadius: 9999, border: 'none', background: 'var(--surface)', boxShadow: 'var(--shadow-sm)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: 'var(--ink)', flexShrink: 0 }}>
        <Icon name="chevL" size={20} sw={2.4} />
      </button>
      <div style={{ flex: 1, fontFamily: 'var(--ff-display)', fontWeight: 800, fontSize: 20, letterSpacing: '-0.02em' }}>{title}</div>
      {trailing}
    </div>
  );
}

// section heading
function SectionHead({ kicker, title, action, onAction }) {
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', padding: '0 20px', marginBottom: 12 }}>
      <div>
        {kicker && <div className="kicker" style={{ marginBottom: 6 }}>{kicker}</div>}
        <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 800, fontSize: 23, letterSpacing: '-0.02em', lineHeight: 1 }}>{title}</div>
      </div>
      {action && <button onClick={onAction} style={{ border: 'none', background: 'none', cursor: 'pointer', color: 'var(--accent)', fontFamily: 'var(--ff-ui)', fontWeight: 700, fontSize: 14, display: 'flex', alignItems: 'center', gap: 3, whiteSpace: 'nowrap', flexShrink: 0 }}>{action}<Icon name="chevR" size={15} sw={2.6} /></button>}
    </div>
  );
}

Object.assign(window, { Stepper, HypeBadge, StockMeter, PriceTag, BrandBar, CategoryRail, PushHeader, SectionHead });
