// Shared UI primitives: Button, IconButton, Pill, Badge, Card, Modal, Toggle, TextInput, Textarea, Avatar.
// Export to window.UI.

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

function classnames(...args) {
  return args.filter(Boolean).join(' ');
}

function Button({ variant = 'primary', size = 'md', children, className = '', icon = null, iconRight = null, full = false, disabled = false, onClick, type = 'button', ...rest }) {
  const sizes = {
    sm: 'h-8 px-3 text-[13px] gap-1.5',
    md: 'h-10 px-4 text-[14px] gap-2',
    lg: 'h-12 px-5 text-[15px] gap-2',
  };
  const variants = {
    primary: 'bg-ink-900 text-white hover:bg-ink-800 active:bg-ink-700 shadow-soft',
    accent:  'bg-violet text-white hover:opacity-90 active:opacity-100 shadow-soft',
    ghost:   'bg-transparent text-ink-800 hover:bg-ink-100 active:bg-ink-200',
    outline: 'bg-white text-ink-900 border border-ink-200 hover:bg-ink-50 active:bg-ink-100',
    danger:  'bg-white text-red-700 border border-red-200 hover:bg-red-50',
    soft:    'bg-ink-100 text-ink-900 hover:bg-ink-200',
  };
  return (
    <button
      type={type}
      onClick={onClick}
      disabled={disabled}
      className={classnames(
        'inline-flex items-center justify-center rounded-full font-medium transition-all duration-150',
        sizes[size], variants[variant],
        full && 'w-full',
        disabled && 'opacity-40 cursor-not-allowed',
        'ring-focus',
        className,
      )}
      {...rest}
    >
      {icon && <span className="-ml-0.5">{icon}</span>}
      {children}
      {iconRight && <span className="-mr-0.5">{iconRight}</span>}
    </button>
  );
}

function IconButton({ children, className = '', onClick, title, variant = 'ghost', size = 'md', ...rest }) {
  const sizes = { sm: 'h-8 w-8', md: 'h-9 w-9', lg: 'h-10 w-10' };
  const variants = {
    ghost: 'hover:bg-ink-100 text-ink-700',
    outline: 'border border-ink-200 bg-white hover:bg-ink-50',
    solid: 'bg-ink-900 text-white hover:bg-ink-800',
  };
  return (
    <button
      onClick={onClick}
      title={title}
      className={classnames('inline-flex items-center justify-center rounded-full transition-colors ring-focus', sizes[size], variants[variant], className)}
      {...rest}
    >
      {children}
    </button>
  );
}

function Pill({ children, active = false, onClick, className = '' }) {
  return (
    <button
      onClick={onClick}
      className={classnames(
        'inline-flex items-center gap-1.5 h-8 px-3 rounded-full text-[13px] font-medium transition-colors',
        active ? 'bg-ink-900 text-white' : 'bg-white border border-ink-200 text-ink-700 hover:bg-ink-50',
        className,
      )}
    >{children}</button>
  );
}

function Badge({ children, variant = 'default', className = '' }) {
  const variants = {
    default: 'bg-ink-100 text-ink-700',
    ready:   'bg-emerald-50 text-emerald-700 border border-emerald-100',
    draft:   'bg-ink-100 text-ink-700',
    sent:    'bg-violet-soft text-violet-ink',
    accent:  'bg-violet text-white',
  };
  return <span className={classnames('inline-flex items-center gap-1 h-6 px-2 rounded-full text-[11px] font-semibold tracking-wide uppercase', variants[variant], className)}>{children}</span>;
}

function Card({ children, className = '', as: As = 'div', ...rest }) {
  return <As className={classnames('bg-white border border-ink-200 rounded-2xl shadow-soft', className)} {...rest}>{children}</As>;
}

function Avatar({ initial, color = '#0F0F0F', size = 32, className = '' }) {
  return (
    <div
      className={classnames('inline-flex items-center justify-center rounded-lg font-semibold text-white shrink-0', className)}
      style={{ width: size, height: size, background: color, fontSize: size * 0.42, letterSpacing: -0.5 }}
    >
      {initial}
    </div>
  );
}

function Modal({ open, onClose, children, title = null, sub = null, wide = false }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose && onClose(); };
    document.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
  }, [open]);
  if (!open) return null;
  return (
    <div className="fixed inset-0 z-50 flex items-end sm:items-center justify-center" onClick={onClose}>
      <div className="absolute inset-0 bg-ink-900/30 backdrop-blur-[2px] fade-in"/>
      <div
        onClick={(e) => e.stopPropagation()}
        className={classnames(
          'relative bg-white border border-ink-200 rounded-t-3xl sm:rounded-3xl w-full sm:max-w-lg shadow-pop slide-up',
          wide && 'sm:max-w-2xl'
        )}
      >
        {(title || sub) && (
          <div className="px-6 pt-6 pb-3 flex items-start justify-between gap-4">
            <div>
              {title && <h3 className="text-[19px] font-semibold tracking-tight">{title}</h3>}
              {sub && <p className="text-[13.5px] text-ink-500 mt-1">{sub}</p>}
            </div>
            <IconButton size="sm" onClick={onClose}><Icons.X size={16}/></IconButton>
          </div>
        )}
        <div className="px-6 pb-6">{children}</div>
      </div>
    </div>
  );
}

function Toggle({ on, onChange, size = 'md' }) {
  const w = size === 'sm' ? 'w-9 h-5' : 'w-11 h-6';
  const knob = size === 'sm' ? 'h-4 w-4' : 'h-5 w-5';
  const tx = size === 'sm' ? (on ? 'translate-x-4' : 'translate-x-0.5') : (on ? 'translate-x-5' : 'translate-x-0.5');
  return (
    <button
      onClick={() => onChange(!on)}
      className={classnames('relative rounded-full transition-colors', w, on ? 'bg-ink-900' : 'bg-ink-200')}
    >
      <span className={classnames('absolute top-0.5 bg-white rounded-full shadow-soft transition-transform', knob, tx)}/>
    </button>
  );
}

function TextInput({ value, onChange, placeholder, type = 'text', icon = null, className = '', size = 'md', ...rest }) {
  const sizes = { sm: 'h-9 text-[13.5px]', md: 'h-11 text-[14.5px]', lg: 'h-12 text-[15px]' };
  return (
    <div className={classnames('relative', className)}>
      {icon && <span className="absolute left-3.5 top-1/2 -translate-y-1/2 text-ink-500">{icon}</span>}
      <input
        type={type}
        value={value}
        onChange={(e) => onChange && onChange(e.target.value)}
        placeholder={placeholder}
        className={classnames(
          'w-full bg-white border border-ink-200 rounded-full px-4 placeholder:text-ink-400 text-ink-900 transition-colors',
          'focus:outline-none focus:border-ink-900',
          icon && 'pl-10',
          sizes[size],
        )}
        {...rest}
      />
    </div>
  );
}

function Textarea({ value, onChange, placeholder, rows = 4, className = '', ...rest }) {
  return (
    <textarea
      value={value}
      onChange={(e) => onChange && onChange(e.target.value)}
      placeholder={placeholder}
      rows={rows}
      className={classnames(
        'w-full bg-white border border-ink-200 rounded-2xl px-4 py-3 text-[14.5px] placeholder:text-ink-400 text-ink-900 transition-colors leading-relaxed',
        'focus:outline-none focus:border-ink-900 resize-none',
        className
      )}
      {...rest}
    />
  );
}

// Empty state
function EmptyState({ icon, title, sub, action = null }) {
  return (
    <div className="relative flex flex-col items-center justify-center py-16 text-center fade-in">
      {/* deco doodles */}
      {window.Doodles && (
        <>
          <window.Doodles.Sparkle size={14} className="absolute top-6 left-1/3 text-violet/70 bob"/>
          <window.Doodles.Sparkle size={10} className="absolute top-10 right-1/3 text-peach-ink/60 bob-2"/>
          <window.Doodles.DashedSwoosh w={70} h={22} className="absolute top-2 left-1/2 -translate-x-1/2 text-ink-300"/>
        </>
      )}
      <div className="h-14 w-14 rounded-2xl bg-ink-100 flex items-center justify-center text-ink-500 mb-4 relative">
        {icon}
      </div>
      <h4 className="text-[17px] font-semibold tracking-tight">{title}</h4>
      {sub && <p className="text-[14px] text-ink-500 mt-1 max-w-md">{sub}</p>}
      {action && <div className="mt-5">{action}</div>}
    </div>
  );
}

// Section header
function SectionHead({ kicker, title, sub, right = null }) {
  return (
    <div className="flex items-end justify-between gap-6 mb-6">
      <div>
        {kicker && <div className="text-[11px] font-semibold uppercase tracking-[0.14em] text-ink-500 mb-2">{kicker}</div>}
        <h2 className="text-[24px] sm:text-[28px] font-semibold tracking-tight" style={{ textWrap: 'balance' }}>{title}</h2>
        {sub && <p className="text-[14.5px] text-ink-500 mt-1.5 max-w-xl" style={{ textWrap: 'pretty' }}>{sub}</p>}
      </div>
      {right && <div className="hidden sm:flex items-center gap-2">{right}</div>}
    </div>
  );
}

// Color swatch input
function ColorSwatch({ color, onChange, onRemove, removable = true, size = 36 }) {
  const ref = useRef(null);
  return (
    <div className="relative group">
      <button
        onClick={() => ref.current && ref.current.click()}
        className="rounded-xl border-2 border-white shadow-soft ring-1 ring-ink-200 hover:scale-105 transition-transform"
        style={{ width: size, height: size, background: color }}
      />
      <input ref={ref} type="color" value={color} onChange={(e) => onChange(e.target.value)} className="absolute opacity-0 inset-0 w-0 h-0"/>
      {removable && onRemove && (
        <button onClick={onRemove} className="absolute -top-1.5 -right-1.5 h-4 w-4 rounded-full bg-ink-900 text-white opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
          <Icons.X size={10} strokeWidth={2.5}/>
        </button>
      )}
    </div>
  );
}

window.UI = { Button, IconButton, Pill, Badge, Card, Avatar, Modal, Toggle, TextInput, Textarea, EmptyState, SectionHead, ColorSwatch, classnames };
