// Lightweight UI primitives for the App UI kit prototype
// (Inline implementations — not from bundle, so testable mid-turn)

function Btn({ children, variant='primary', size='md', iconLeft, iconRight, fullWidth, disabled, onClick, style }) {
  const [hov, setHov] = React.useState(false);
  const h = { sm:32, md:40, lg:48 }[size]||40;
  const p = { sm:'0 12px', md:'0 16px', lg:'0 22px' }[size]||'0 16px';
  const fs = { sm:'var(--text-sm)', md:'var(--text-base)', lg:'var(--text-md)' }[size]||'var(--text-base)';
  const v = {
    primary:   { background: hov&&!disabled?'#000':'var(--ink-950)', color:'var(--paper-0)', border:'1px solid var(--ink-950)' },
    accent:    { background: hov&&!disabled?'var(--lime-600)':'var(--lime-500)', color:'var(--ink-950)', border:'1px solid var(--lime-500)' },
    secondary: { background: hov&&!disabled?'var(--surface-muted)':'var(--surface-card)', color:'var(--text-strong)', border:'1px solid var(--border-strong)' },
    ghost:     { background: hov&&!disabled?'var(--surface-muted)':'transparent', color:'var(--text-body)', border:'1px solid transparent' },
    danger:    { background: hov&&!disabled?'var(--red-700)':'var(--red-600)', color:'#fff', border:'1px solid var(--red-600)' },
  }[variant]||{};
  return (
    <button disabled={disabled} onClick={onClick}
      onMouseEnter={()=>setHov(true)} onMouseLeave={()=>setHov(false)}
      style={{ display:fullWidth?'flex':'inline-flex', width:fullWidth?'100%':'auto', alignItems:'center', justifyContent:'center',
        gap:8, height:h, padding:p, border:'none', borderRadius:'var(--radius-md)',
        font:`var(--weight-semibold) ${fs}/1 var(--font-sans)`, letterSpacing:'-0.01em',
        cursor:disabled?'not-allowed':'pointer', opacity:disabled?0.45:1, whiteSpace:'nowrap',
        transition:'background var(--dur-fast), transform var(--dur-fast)',
        transform:hov&&!disabled?'translateY(-1px)':'none', ...v, ...style }} >
      {iconLeft&&<span style={{display:'inline-flex'}}>{iconLeft}</span>}
      {children}
      {iconRight&&<span style={{display:'inline-flex'}}>{iconRight}</span>}
    </button>
  );
}

function IcoBtn({ icon, variant='ghost', size='md', title, onClick, style }) {
  const [hov, setHov] = React.useState(false);
  const dim = { sm:30, md:36, lg:42 }[size]||36;
  const v = {
    solid:   { background:hov?'#000':'var(--ink-950)', color:'var(--paper-0)' },
    soft:    { background:hov?'var(--surface-muted)':'var(--paper-2)', color:'var(--text-strong)' },
    outline: { background:hov?'var(--surface-muted)':'var(--surface-card)', color:'var(--text-body)', border:'1px solid var(--border-strong)' },
    ghost:   { background:hov?'var(--surface-muted)':'transparent', color:hov?'var(--text-strong)':'var(--text-secondary)' },
  }[variant]||{};
  return (
    <button type="button" title={title} aria-label={title} onClick={onClick}
      onMouseEnter={()=>setHov(true)} onMouseLeave={()=>setHov(false)}
      style={{ display:'inline-flex', alignItems:'center', justifyContent:'center',
        width:dim, height:dim, padding:0, border:'none', borderRadius:'var(--radius-md)',
        cursor:'pointer', transition:'background var(--dur-fast)', ...v, ...style }}>
      {icon}
    </button>
  );
}

function Bdg({ children, tone='neutral', variant='soft', dot, size='md', style }) {
  const T = {
    neutral: { fg:'var(--ink-700)', bg:'var(--surface-muted)', solid:'var(--ink-900)', bdr:'var(--border-strong)' },
    brand:   { fg:'var(--lime-700)', bg:'var(--brand-tint)', solid:'var(--lime-600)', bdr:'var(--lime-400)' },
    approve: { fg:'var(--approve-fg)', bg:'var(--approve-bg)', solid:'var(--approve-solid)', bdr:'var(--green-500)' },
    maybe:   { fg:'var(--maybe-fg)', bg:'var(--maybe-bg)', solid:'var(--maybe-solid)', bdr:'var(--amber-500)' },
    reject:  { fg:'var(--reject-fg)', bg:'var(--reject-bg)', solid:'var(--reject-solid)', bdr:'var(--red-500)' },
    pending: { fg:'var(--pending-fg)', bg:'var(--pending-bg)', solid:'var(--pending-solid)', bdr:'var(--blue-500)' },
  }[tone]||{};
  const h = size==='sm'?20:24, p = size==='sm'?'0 7px':'0 9px', fs = size==='sm'?'var(--text-2xs)':'var(--text-xs)';
  const skin = variant==='solid' ? { background:T.solid, color:tone==='brand'?'var(--ink-950)':'#fff' }
    : variant==='outline' ? { background:'transparent', color:T.fg, border:`1px solid ${T.bdr}` }
    : { background:T.bg, color:T.fg };
  return (
    <span style={{ display:'inline-flex', alignItems:'center', gap:5, height:h, padding:p,
      borderRadius:'var(--radius-pill)', font:`var(--weight-semibold) ${fs}/1 var(--font-sans)`,
      whiteSpace:'nowrap', ...skin, ...style }}>
      {dot&&<span style={{ width:6, height:6, borderRadius:'50%', background:T.solid, flexShrink:0 }} />}
      {children}
    </span>
  );
}

function RecBdg({ value='pending', emphasis='soft', size='md', style }) {
  const MAP = {
    approved:{label:'Approved',tone:'approve',g:'✓'}, strongyes:{label:'Strong Yes',tone:'approve',g:'✓'},
    shortlist:{label:'Shortlist',tone:'maybe',g:'~'}, maybe:{label:'Maybe',tone:'maybe',g:'~'},
    rejected:{label:'Rejected',tone:'reject',g:'×'}, no:{label:'No',tone:'reject',g:'×'},
    pending:{label:'Pending',tone:'pending',g:'◷'},
  };
  const T2 = {
    approve:{fg:'var(--approve-fg)',bg:'var(--approve-bg)',s:'var(--approve-solid)'},
    maybe:{fg:'var(--maybe-fg)',bg:'var(--maybe-bg)',s:'var(--maybe-solid)'},
    reject:{fg:'var(--reject-fg)',bg:'var(--reject-bg)',s:'var(--reject-solid)'},
    pending:{fg:'var(--pending-fg)',bg:'var(--pending-bg)',s:'var(--pending-solid)'},
  };
  const m = MAP[String(value).toLowerCase().replace(/\s+/g,'')] || MAP.pending;
  const t = T2[m.tone];
  const h = size==='sm'?22:28, p = size==='sm'?'0 8px':'0 11px', fs = size==='sm'?'var(--text-xs)':'var(--text-sm)';
  const strong = emphasis==='strong';
  const gd = size==='sm'?13:15;
  return (
    <span style={{ display:'inline-flex', alignItems:'center', gap:6, height:h, padding:p,
      borderRadius:'var(--radius-pill)', font:`var(--weight-bold) ${fs}/1 var(--font-sans)`,
      background:strong?t.s:t.bg, color:strong?'#fff':t.fg, whiteSpace:'nowrap', ...style }}>
      <span style={{ display:'inline-flex', alignItems:'center', justifyContent:'center',
        width:gd, height:gd, borderRadius:'50%', background:strong?'rgba(255,255,255,0.22)':t.s,
        color:'#fff', fontSize:gd-3, fontWeight:700, lineHeight:1 }}>{m.g}</span>
      {m.label}
    </span>
  );
}

function Tgl({ checked, defaultChecked=false, onChange, label, description, disabled }) {
  const [on, setOn] = React.useState(checked!==undefined?checked:defaultChecked);
  const val = checked!==undefined?checked:on;
  const toggle = () => { if(disabled)return; const n=!val; if(checked===undefined)setOn(n); onChange&&onChange(n); };
  const track = (
    <button type="button" role="switch" aria-checked={val} onClick={toggle} disabled={disabled}
      style={{ position:'relative', flexShrink:0, width:40, height:24, padding:0, border:'none',
        borderRadius:'var(--radius-pill)', cursor:disabled?'not-allowed':'pointer',
        background:val?'var(--ink-950)':'var(--surface-muted)',
        boxShadow:`inset 0 0 0 1px ${val?'var(--ink-950)':'var(--border-strong)'}`,
        transition:'background var(--dur-base)' }}>
      <span style={{ position:'absolute', top:3, left:val?18:3, width:18, height:18,
        borderRadius:'50%', background:val?'var(--lime-500)':'#fff',
        boxShadow:'0 1px 3px rgba(0,0,0,0.15)',
        transition:'left var(--dur-base) var(--ease-spring), background var(--dur-base)' }} />
    </button>
  );
  if(!label) return track;
  return (
    <label style={{ display:'flex', gap:12, alignItems:description?'flex-start':'center', cursor:'pointer' }}>
      {track}
      <span style={{ display:'flex', flexDirection:'column', gap:2 }}>
        <span style={{ font:'var(--type-label)', color:'var(--text-strong)' }}>{label}</span>
        {description&&<span style={{ font:'var(--type-caption)', color:'var(--text-muted)' }}>{description}</span>}
      </span>
    </label>
  );
}

function Seg({ options=[], value, defaultValue, onChange, size='md', fullWidth }) {
  const [internal, setInternal] = React.useState(defaultValue||(options[0]?.value||options[0]));
  const cur = value!==undefined?value:internal;
  const h = size==='sm'?30:38, p = size==='sm'?'0 12px':'0 16px', fs = size==='sm'?'var(--text-sm)':'var(--text-base)';
  const select = v => { if(value===undefined)setInternal(v); onChange&&onChange(v); };
  return (
    <div role="tablist" style={{ display:fullWidth?'grid':'inline-grid', gridAutoFlow:'column',
      gridAutoColumns:fullWidth?'1fr':'auto', gap:3, padding:3,
      background:'var(--surface-muted)', border:'1px solid var(--border)', borderRadius:'var(--radius-md)' }}>
      {options.map(opt => {
        const v = opt.value||opt, lbl = opt.label||opt, active = cur===v;
        return (
          <button key={v} type="button" onClick={()=>select(v)} style={{ display:'inline-flex', alignItems:'center',
            justifyContent:'center', gap:6, height:h, padding:p, border:'none', cursor:'pointer',
            borderRadius:'var(--radius-sm)', font:`var(--weight-semibold) ${fs}/1 var(--font-sans)`,
            background:active?'var(--ink-950)':'transparent',
            color:active?'var(--paper-0)':'var(--text-secondary)',
            boxShadow:active?'var(--shadow-sm)':'none',
            transition:'background var(--dur-fast), color var(--dur-fast)' }}>{lbl}</button>
        );
      })}
    </div>
  );
}

function Fld({ label, value, defaultValue, placeholder, mono, trailing, iconLeft, hint, error, onChange, type='text', style }) {
  const [focus, setFocus] = React.useState(false);
  const [internal, setInternal] = React.useState(defaultValue||'');
  const val = value!==undefined?value:internal;
  const bc = error?'var(--reject-solid)':focus?'var(--lime-500)':'var(--border-strong)';
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:6, ...style }}>
      {label&&<label style={{ font:'var(--type-label)', color:'var(--text-strong)' }}>{label}</label>}
      <div style={{ display:'flex', alignItems:'center', gap:8, height:42, padding:'0 12px',
        background:'var(--surface-card)', border:`1px solid ${bc}`,
        borderRadius:'var(--radius-md)', boxShadow:focus?'var(--ring)':'none',
        transition:'border-color var(--dur-fast), box-shadow var(--dur-fast)' }}>
        {iconLeft&&<span style={{ display:'inline-flex', color:'var(--text-muted)', flexShrink:0 }}>{iconLeft}</span>}
        <input type={type} value={val} placeholder={placeholder}
          onFocus={()=>setFocus(true)} onBlur={()=>setFocus(false)}
          onChange={e=>{setInternal(e.target.value);onChange&&onChange(e)}}
          style={{ flex:1, minWidth:0, border:'none', outline:'none', background:'transparent',
            font:mono?'var(--weight-medium) var(--text-base)/1 var(--font-mono)':'var(--type-body)',
            color:'var(--text-strong)' }} />
        {trailing&&<span style={{ font:'var(--type-caption)', color:'var(--text-muted)', flexShrink:0 }}>{trailing}</span>}
      </div>
      {hint&&<span style={{ font:'var(--type-caption)', color:'var(--text-muted)' }}>{hint}</span>}
    </div>
  );
}

function TA({ label, value, defaultValue, placeholder, rows=4, maxLength, showCount, onChange, style }) {
  const [focus, setFocus] = React.useState(false);
  const [len, setLen] = React.useState((defaultValue||'').length);
  const [internal, setInternal] = React.useState(defaultValue||'');
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:6, ...style }}>
      {label&&<label style={{ font:'var(--type-label)', color:'var(--text-strong)' }}>{label}</label>}
      <textarea value={value!==undefined?value:internal} placeholder={placeholder} rows={rows} maxLength={maxLength}
        onFocus={()=>setFocus(true)} onBlur={()=>setFocus(false)}
        onChange={e=>{setLen(e.target.value.length);setInternal(e.target.value);onChange&&onChange(e)}}
        style={{ resize:'vertical', padding:'12px 14px', background:'var(--surface-card)',
          border:`1px solid ${focus?'var(--lime-500)':'var(--border-strong)'}`,
          borderRadius:'var(--radius-md)', boxShadow:focus?'var(--ring)':'none',
          outline:'none', font:'var(--type-body)', color:'var(--text-strong)', lineHeight:'var(--leading-normal)',
          transition:'border-color var(--dur-fast), box-shadow var(--dur-fast)' }} />
      {showCount&&<div style={{ display:'flex', justifyContent:'flex-end', font:'var(--type-caption)', color:'var(--text-muted)' }}>
        <span className="tnum">{maxLength?`${len}/${maxLength}`:len}</span>
      </div>}
    </div>
  );
}

// Inline SVG icon helper
const I = ({d,s=15}) => (
  <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">{d}</svg>
);
const Icons = {
  campaign: <I d={<><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></>} />,
  reports:  <I d={<><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></>} />,
  settings: <I d={<><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></>} />,
  external: <I d={<><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></>} />,
  copy:     <I d={<><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></>} />,
  info:     <I d={<><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></>} />,
  warn:     <I d={<><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><path d="M12 9v4"/><path d="M12 17h.01"/></>} />,
  check:    <I d={<><path d="M20 6 9 17l-5-5"/></>} />,
  list:     <I d={<><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></>} />,
  grid:     <I d={<><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></>} />,
  download: <I d={<><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></>} />,
  sparkles: <I d={<><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/></>} />,
  plus:     <I d={<><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></>} />,
};

Object.assign(window, { Btn, IcoBtn, Bdg, RecBdg, Tgl, Seg, Fld, TA, Icons, I });
