// ───────────────────────── Reusable UI primitives ─────────────────────────
const cx = (...a) => a.filter(Boolean).join(' ');

function Button({ children, variant = 'primary', size = 'md', icon, iconRight, className = '', onClick, disabled, type = 'button', title }) {
  const base = 'inline-flex items-center justify-center gap-2 font-semibold rounded-xl transition-all duration-150 active:scale-[.985] disabled:opacity-40 disabled:pointer-events-none whitespace-nowrap';
  const sizes = { sm: 'text-[13px] px-3.5 py-2', md: 'text-sm px-5 py-2.5', lg: 'text-[15px] px-6 py-3.5' };
  const variants = {
    primary:   'bg-primary text-white hover:bg-primary-600',
    dark:      'bg-slate2 text-white hover:bg-[#1f2230]',
    outline:   'bg-white text-ink border border-line hover:border-primary-300 hover:text-primary-800 hover:bg-primary-50/40',
    ghost:     'bg-transparent text-muted hover:bg-black/[0.04] hover:text-ink',
    softprim:  'bg-primary-50 text-primary-800 hover:bg-primary-100',
    danger:    'bg-white text-[#E45455] border border-[#f3c9c9] hover:bg-[#fdeced]',
  };
  return (
    <button type={type} title={title} onClick={onClick} disabled={disabled} className={cx(base, sizes[size], variants[variant], className)}>
      {icon && <Icon name={icon} size={size === 'lg' ? 20 : 18} strokeWidth={2} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === 'lg' ? 20 : 18} strokeWidth={2} />}
    </button>
  );
}

function IconButton({ name, label, onClick, size = 18, className = '', tone = 'default' }) {
  const tones = {
    default: 'text-muted hover:text-ink hover:bg-black/[0.05]',
    primary: 'text-primary-800 hover:bg-primary-50',
    danger:  'text-[#E45455] hover:bg-[#fdeced]',
  };
  return (
    <button onClick={onClick} title={label} aria-label={label}
      className={cx('inline-flex items-center justify-center rounded-lg w-9 h-9 transition-colors', tones[tone], className)}>
      <Icon name={name} size={size} strokeWidth={2} />
    </button>
  );
}

function Card({ children, className = '', hover = false, onClick, style, id }) {
  return (
    <div id={id} style={style} onClick={onClick} className={cx('bg-white rounded-2xl border border-line shadow-card', hover && 'transition-shadow hover:shadow-cardhover', className)}>
      {children}
    </div>
  );
}

function Switch({ checked, onChange, label, sub }) {
  return (
    <button onClick={() => onChange(!checked)} className="flex items-center gap-3 group text-left">
      <span className={cx('relative w-11 h-6 rounded-full transition-colors duration-200 shrink-0', checked ? 'bg-primary' : 'bg-[#d9d9e0]')}>
        <span className={cx('absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform duration-200', checked && 'translate-x-5')} />
      </span>
      {label && <span className="text-sm font-medium text-ink">{label}</span>}
      {sub && <span className="text-[13px] text-muted">{sub}</span>}
    </button>
  );
}

function Checkbox({ checked, onChange, className = '' }) {
  return (
    <span role="checkbox" aria-checked={checked} tabIndex={0}
      onClick={(e) => { e.stopPropagation(); onChange(!checked); }}
      className={cx('w-5 h-5 rounded-[6px] border-2 flex items-center justify-center transition-all shrink-0 cursor-pointer',
        checked ? 'bg-primary border-primary' : 'bg-white border-[#cdcdd6] hover:border-primary-300', className)}>
      {checked && <Icon name="check" size={13} strokeWidth={3} className="text-white" />}
    </span>
  );
}

function Radio({ checked, onChange, className = '' }) {
  return (
    <span role="radio" aria-checked={checked} tabIndex={0}
      onClick={(e) => { e.stopPropagation(); onChange(); }}
      className={cx('w-5 h-5 rounded-full border-2 flex items-center justify-center transition-all shrink-0 cursor-pointer',
        checked ? 'border-primary' : 'border-[#cdcdd6] hover:border-primary-300', className)}>
      {checked && <span className="w-2.5 h-2.5 rounded-full bg-primary" />}
    </span>
  );
}

function Segmented({ options, value, onChange, className = '' }) {
  return (
    <div className={cx('inline-flex p-1 bg-canvas rounded-xl border border-line', className)}>
      {options.map((o) => (
        <button key={o.value} onClick={() => onChange(o.value)}
          className={cx('px-4 py-2 rounded-lg text-sm font-semibold transition-all duration-150 flex items-center gap-2',
            value === o.value ? 'bg-white text-primary-800 shadow-card' : 'text-muted hover:text-ink')}>
          {o.icon && <Icon name={o.icon} size={16} strokeWidth={2} />}
          {o.label}
        </button>
      ))}
    </div>
  );
}

function Stepper({ value, onChange, min = 1, max = 50 }) {
  const set = (v) => onChange(Math.max(min, Math.min(max, v)));
  return (
    <div className="inline-flex items-center bg-white border border-line rounded-xl overflow-hidden">
      <button onClick={() => set(value - 1)} className="w-10 h-10 flex items-center justify-center text-muted hover:bg-canvas hover:text-primary-800 transition-colors">
        <Icon name="minus" size={18} strokeWidth={2.4} />
      </button>
      <span className="w-12 text-center text-[15px] font-bold text-ink tabular-nums">{value}</span>
      <button onClick={() => set(value + 1)} className="w-10 h-10 flex items-center justify-center text-muted hover:bg-canvas hover:text-primary-800 transition-colors">
        <Icon name="plus" size={18} strokeWidth={2.4} />
      </button>
    </div>
  );
}

function Select({ value, onChange, options, placeholder = 'Selecciona…', icon, className = '' }) {
  return (
    <div className={cx('relative', className)}>
      {icon && <Icon name={icon} size={18} className="absolute left-3.5 top-1/2 -translate-y-1/2 text-muted pointer-events-none" />}
      <select value={value} onChange={(e) => onChange(e.target.value)}
        className={cx('w-full appearance-none bg-white border border-line rounded-xl py-3 pr-10 text-sm font-medium text-ink cursor-pointer transition-colors hover:border-primary-300 focus:border-primary focus:ring-2 focus:ring-primary-100', icon ? 'pl-11' : 'pl-4')}>
        {!value && <option value="">{placeholder}</option>}
        {options.map((o) => {
          const val = typeof o === 'string' ? o : o.value;
          const lab = typeof o === 'string' ? o : o.label;
          return <option key={val} value={val}>{lab}</option>;
        })}
      </select>
      <Icon name="chevron-down" size={18} className="absolute right-3.5 top-1/2 -translate-y-1/2 text-muted pointer-events-none" />
    </div>
  );
}

function Badge({ children, tone = 'neutral', className = '' }) {
  const tones = {
    neutral: 'bg-canvas text-muted border border-line',
    primary: 'bg-primary-50 text-primary-800',
    green:   'bg-[#e7f7ee] text-[#1f8a52]',
    amber:   'bg-[#fff4e5] text-[#c77700]',
    purple:  'bg-[#efeaff] text-[#6a51d6]',
    rose:    'bg-[#fdeaec] text-[#c0344b]',
  };
  return <span className={cx('inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11.5px] font-semibold leading-none', tones[tone], className)}>{children}</span>;
}

// difficulty pill colors (consistent app-wide)
function DifficultyTag({ value }) {
  const map = (window.DIFFICULTY_TONE) || { Bajo: 'green', Medio: 'amber', Alto: 'rose' };
  return <Badge tone={map[value] || 'neutral'}>{value}</Badge>;
}

Object.assign(window, { cx, Button, IconButton, Card, Switch, Checkbox, Radio, Segmented, Stepper, Select, Badge, DifficultyTag, SelectAllPair });

// Par unificado "Seleccionar todo / Quitar todo" (mismo aspecto en toda la web)
function SelectAllPair({ allOn, onSelectAll, onClear, hasSelection, labelAll = 'Seleccionar todo', labelClear = 'Quitar todo' }) {
  return (
    <div className="flex items-center gap-1.5 shrink-0">
      <Button variant="outline" size="sm" icon="check" onClick={onSelectAll} disabled={allOn}>{labelAll}</Button>
      <Button variant="ghost" size="sm" onClick={onClear} disabled={!hasSelection}>{labelClear}</Button>
    </div>
  );
}
