/* global React */
// wf-mobile · primitives.jsx
// Reusable UI primitives: MobileShell, BottomTabs, Sheet, Toast, Avatar, FakeQR, FakeBarcode.
window.WFMobile = window.WFMobile || {};
const { Icon } = window.WFMobile;

function MobileShell({ header, children, tabs, sheet, toast, bg = 'paper', appProps }) {
  return (
    <div className="wm-app" data-bg={bg} {...(appProps || {})}>
      {header}
      <div className="wm-content"><div className="wm-enter wm-stack">{children}</div></div>
      {tabs}
      {sheet}
      {toast}
    </div>
  );
}

function MobileHeader({ title, sub, left, right, variant }) {
  return (
    <div className="wm-header" data-variant={variant}>
      <div>
        {left || null}
        <div className="wm-hd-title">{title}</div>
        {sub ? <div className="wm-hd-sub">{sub}</div> : null}
      </div>
      <div className="wm-hd-actions">{right}</div>
    </div>
  );
}

function BottomTabs({ items, active, onChange }) {
  return (
    <div className="wm-tabs" role="tablist" style={{ '--wm-tabs-count': items.length }}>
      {items.map((it) => {
        const isActive = active === it.key;
        const iconName = isActive && it.iconFill ? it.iconFill : it.icon;
        return (
          <button key={it.key} className={'wm-tab ' + (isActive ? 'active' : '')}
                  onClick={() => onChange(it.key)} role="tab" aria-selected={isActive}>
            <span className="wm-tab-icon"><Icon name={iconName} size={24} /></span>
            <span>{it.label}</span>
          </button>
        );
      })}
    </div>
  );
}

function Avatar({ name = '?', size = 'md', tone }) {
  const initials = name.split(/\s+/).slice(0, 2).map((s) => s[0]).join('').toUpperCase();
  const cls = size === 'lg' ? 'wm-avatar lg' : size === 'sm' ? 'wm-avatar sm' : 'wm-avatar';
  const bg = tone || `linear-gradient(135deg, hsl(${(name.charCodeAt(0) * 13) % 360} 70% 55%), hsl(${(name.charCodeAt(1) * 17) % 360} 60% 40%))`;
  return <div className={cls} style={{ background: bg }}>{initials}</div>;
}

function Sheet({ open, title, onClose, children, footer }) {
  if (!open) return null;
  return (
    <>
      <div className="wm-sheet-backdrop" onClick={onClose} />
      <div className="wm-sheet">
        <div className="wm-sheet-handle" />
        {title ? <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom: 16 }}>
          <h3 className="wm-h3">{title}</h3>
          <button className="wm-icon-btn" onClick={onClose}><Icon name="close" size={18}/></button>
        </div> : null}
        <div>{children}</div>
        {footer ? <div style={{ marginTop: 16 }}>{footer}</div> : null}
      </div>
    </>
  );
}

function Toast({ message, icon = 'check' }) {
  if (!message) return null;
  return (
    <div className="wm-toast">
      <Icon name={icon} size={14} color="#fff"/>
      <span>{message}</span>
    </div>
  );
}

// Visual-only QR — geometric noise with finder squares
function FakeQR({ size = 220 }) {
  const cells = 25;
  const cellSize = size / cells;
  const rows = [];
  // deterministic pseudo-noise
  let seed = 7;
  const rand = () => { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; };
  for (let y = 0; y < cells; y++) {
    for (let x = 0; x < cells; x++) {
      const inFinder = (x < 7 && y < 7) || (x > cells - 8 && y < 7) || (x < 7 && y > cells - 8);
      if (inFinder) continue;
      if (rand() > 0.52) {
        rows.push(<rect key={x+','+y} x={x*cellSize} y={y*cellSize} width={cellSize} height={cellSize} fill="#0c0a09"/>);
      }
    }
  }
  const finder = (cx, cy) => (
    <g key={cx+'-'+cy}>
      <rect x={cx*cellSize} y={cy*cellSize} width={cellSize*7} height={cellSize*7} fill="#0c0a09" rx="6"/>
      <rect x={(cx+1)*cellSize} y={(cy+1)*cellSize} width={cellSize*5} height={cellSize*5} fill="#fff" rx="4"/>
      <rect x={(cx+2)*cellSize} y={(cy+2)*cellSize} width={cellSize*3} height={cellSize*3} fill="#0c0a09" rx="2"/>
    </g>
  );
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <rect width={size} height={size} fill="#fff"/>
      {rows}
      {finder(0,0)}{finder(cells-7,0)}{finder(0,cells-7)}
    </svg>
  );
}

function FakeBarcode({ width = 260, height = 80, value = '0123456789' }) {
  const bars = [];
  let x = 0;
  let seed = 11;
  const rand = () => { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; };
  while (x < width) {
    const w = 1 + Math.floor(rand() * 4);
    const black = rand() > 0.3;
    if (black) bars.push(<rect key={x} x={x} y={0} width={w} height={height-22} fill="#0c0a09"/>);
    x += w + 1;
  }
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      <rect width={width} height={height} fill="#fff"/>
      {bars}
      <text x={width/2} y={height-6} textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="11" fill="#0c0a09" letterSpacing="3">{value}</text>
    </svg>
  );
}

window.WFMobile.MobileShell = MobileShell;
window.WFMobile.MobileHeader = MobileHeader;
window.WFMobile.BottomTabs = BottomTabs;
window.WFMobile.Avatar = Avatar;
window.WFMobile.Sheet = Sheet;
window.WFMobile.Toast = Toast;
window.WFMobile.FakeQR = FakeQR;
window.WFMobile.FakeBarcode = FakeBarcode;
