// aerOS — shared primitives. Built on ds.css tokens. Exports to window.
const { useState, useRef, useEffect, useMemo, useCallback } = React;

/* ----------------------------- Button ----------------------------- */
function Button({ children, variant = 'secondary', size = 'md', icon, iconRight, full, onClick, disabled, type = 'button', brand = false, title }) {
  const [hover, setHover] = useState(false);
  const accent = brand ? 'var(--brand)' : 'var(--accent)';
  const onAccent = brand ? 'var(--on-brand)' : 'var(--on-accent)';
  const sizes = {
    sm: { h: 30, px: 10, fs: 12.5, gap: 6 },
    md: { h: 38, px: 14, fs: 13.5, gap: 7 },
    lg: { h: 46, px: 20, fs: 15, gap: 8 },
  }[size];
  const base = {
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    gap: sizes.gap, height: sizes.h, padding: `0 ${sizes.px}px`,
    borderRadius: 'var(--r-sm)', fontSize: sizes.fs, fontWeight: 600,
    cursor: disabled ? 'not-allowed' : 'pointer', fontFamily: 'inherit',
    transition: 'all 120ms', whiteSpace: 'nowrap', width: full ? '100%' : undefined,
    opacity: disabled ? 0.5 : 1, lineHeight: 1,
  };
  const variants = {
    primary: { background: accent, color: onAccent, border: `1px solid ${accent}`, filter: hover && !disabled ? 'brightness(0.92)' : 'none' },
    secondary: { background: 'var(--bg-0)', color: 'var(--fg-1)', border: '1px solid var(--border)', boxShadow: 'var(--shadow-sm)', background: hover && !disabled ? 'var(--bg-3)' : 'var(--bg-0)' },
    ghost: { background: hover && !disabled ? 'var(--bg-3)' : 'transparent', color: 'var(--fg-2)', border: '1px solid transparent' },
    danger: { background: hover && !disabled ? '#c81e1e' : 'var(--danger)', color: '#fff', border: '1px solid var(--danger)' },
    dangerSoft: { background: 'var(--danger-soft)', color: 'var(--danger)', border: '1px solid transparent' },
    outline: { background: hover && !disabled ? accent : 'transparent', color: hover && !disabled ? onAccent : accent, border: `1px solid ${accent}` },
  };
  return (
    <button type={type} onClick={disabled ? undefined : onClick} disabled={disabled} title={title}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{ ...base, ...variants[variant] }}>
      {icon && <span style={{ display: 'flex' }}>{typeof icon === 'function' ? icon({ size: sizes.fs + 3 }) : icon}</span>}
      {children}
      {iconRight && <span style={{ display: 'flex' }}>{typeof iconRight === 'function' ? iconRight({ size: sizes.fs + 3 }) : iconRight}</span>}
    </button>
  );
}

function IconButton({ icon, title, onClick, active, size = 34, tone, badge }) {
  const [hover, setHover] = useState(false);
  return (
    <button type="button" title={title} onClick={onClick}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        position: 'relative', width: size, height: size, borderRadius: 'var(--r-sm)',
        border: '1px solid ' + (active ? 'var(--border)' : 'transparent'),
        background: active ? 'var(--bg-3)' : (hover ? 'var(--bg-3)' : 'transparent'),
        color: tone || 'var(--fg-2)', cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
        transition: 'all 120ms',
      }}>
      {typeof icon === 'function' ? icon({ size: 18 }) : icon}
      {badge != null && (
        <span style={{
          position: 'absolute', top: -3, right: -3, minWidth: 16, height: 16, padding: '0 4px',
          borderRadius: 8, background: 'var(--danger)', color: '#fff', fontSize: 10, fontWeight: 700,
          display: 'flex', alignItems: 'center', justifyContent: 'center', border: '2px solid var(--bg-0)',
        }}>{badge}</span>
      )}
    </button>
  );
}

/* ----------------------------- Field + inputs ----------------------------- */
function Field({ label, children, hint, error, required, span, full }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6, minWidth: 0, gridColumn: span ? `span ${span}` : (full ? '1 / -1' : undefined) }}>
      {label && (
        <label style={{ fontSize: 11, fontWeight: 600, color: 'var(--fg-2)', letterSpacing: '0.03em', textTransform: 'uppercase', display: 'flex', alignItems: 'center', gap: 4 }}>
          {label}{required && <span style={{ color: 'var(--danger)' }}>*</span>}
        </label>
      )}
      {children}
      {error ? <div style={{ fontSize: 11.5, color: 'var(--danger)' }}>{error}</div>
        : hint && <div style={{ fontSize: 11.5, color: 'var(--fg-3)' }}>{hint}</div>}
    </div>
  );
}

function Input({ value, onChange, placeholder, type = 'text', suffix, prefix, icon, readOnly, disabled, align = 'left', error, onKeyDown, autoFocus, min, max }) {
  const [focus, setFocus] = useState(false);
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 8, height: 38, padding: '0 11px',
      background: readOnly || disabled ? 'var(--bg-2)' : 'var(--bg-1)',
      border: `1px solid ${error ? 'var(--danger)' : focus ? 'var(--brand)' : 'var(--border)'}`,
      borderRadius: 'var(--r-sm)', transition: 'border-color 120ms, box-shadow 120ms',
      boxShadow: focus ? '0 0 0 3px var(--brand-ring)' : 'none', opacity: disabled ? 0.6 : 1,
    }}>
      {icon && <span style={{ color: 'var(--fg-3)', display: 'flex', flexShrink: 0 }}>{typeof icon === 'function' ? icon({ size: 15 }) : icon}</span>}
      {prefix && <span style={{ color: 'var(--fg-3)', fontSize: 13, flexShrink: 0 }}>{prefix}</span>}
      <input type={type} value={value ?? ''} min={min} max={max}
        onChange={e => onChange && onChange(e.target.value)} placeholder={placeholder}
        readOnly={readOnly} disabled={disabled} autoFocus={autoFocus} onKeyDown={onKeyDown}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
        style={{ flex: 1, border: 'none', outline: 'none', background: 'transparent', fontSize: 14, color: 'var(--fg-1)', fontFamily: 'inherit', minWidth: 0, textAlign: align, fontVariantNumeric: align === 'right' || type === 'number' ? 'tabular-nums' : 'normal' }} />
      {suffix && <span style={{ color: 'var(--fg-3)', fontSize: 12.5, flexShrink: 0 }}>{suffix}</span>}
    </div>
  );
}

function Textarea({ value, onChange, placeholder, rows = 4, readOnly }) {
  const [focus, setFocus] = useState(false);
  return (
    <textarea value={value ?? ''} onChange={e => onChange && onChange(e.target.value)} placeholder={placeholder} rows={rows} readOnly={readOnly}
      onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
      style={{ width: '100%', padding: '10px 12px', border: `1px solid ${focus ? 'var(--brand)' : 'var(--border)'}`, borderRadius: 'var(--r-sm)', fontSize: 14, fontFamily: 'inherit', resize: 'vertical', background: 'var(--bg-1)', color: 'var(--fg-1)', outline: 'none', lineHeight: 1.5, boxShadow: focus ? '0 0 0 3px var(--brand-ring)' : 'none', transition: 'all 120ms' }} />
  );
}

function Select({ value, onChange, options, placeholder, disabled }) {
  const [focus, setFocus] = useState(false);
  const opts = options.map(o => typeof o === 'object' ? o : { value: o, label: o });
  return (
    <div style={{ position: 'relative', display: 'flex', alignItems: 'center', height: 38, padding: '0 11px', background: disabled ? 'var(--bg-2)' : 'var(--bg-1)', border: `1px solid ${focus ? 'var(--brand)' : 'var(--border)'}`, borderRadius: 'var(--r-sm)', boxShadow: focus ? '0 0 0 3px var(--brand-ring)' : 'none', opacity: disabled ? 0.6 : 1, transition: 'all 120ms' }}>
      <select value={value ?? ''} onChange={e => onChange && onChange(e.target.value)} disabled={disabled}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
        style={{ flex: 1, border: 'none', outline: 'none', background: 'transparent', fontSize: 14, color: value !== '' && value != null ? 'var(--fg-1)' : 'var(--fg-3)', fontFamily: 'inherit', appearance: 'none', paddingRight: 18, cursor: 'pointer' }}>
        {placeholder && <option value="">{placeholder}</option>}
        {opts.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
      </select>
      <span style={{ pointerEvents: 'none', color: 'var(--fg-3)', display: 'flex', position: 'absolute', right: 9 }}>{Icon.chevDown({ size: 15 })}</span>
    </div>
  );
}

function Switch({ checked, onChange, disabled }) {
  return (
    <button type="button" role="switch" aria-checked={checked} disabled={disabled} onClick={() => !disabled && onChange(!checked)}
      style={{ width: 40, height: 23, borderRadius: 12, border: 'none', padding: 2, cursor: disabled ? 'not-allowed' : 'pointer', background: checked ? 'var(--brand)' : 'var(--border-strong)', transition: 'background 160ms', display: 'flex', alignItems: 'center', opacity: disabled ? 0.5 : 1 }}>
      <span style={{ width: 19, height: 19, borderRadius: '50%', background: '#fff', boxShadow: '0 1px 3px rgba(0,0,0,0.25)', transform: checked ? 'translateX(17px)' : 'translateX(0)', transition: 'transform 160ms' }} />
    </button>
  );
}

function Check({ label, checked, onChange, tone = 'brand', disabled }) {
  const tones = { brand: 'var(--brand)', default: 'var(--accent)', warn: 'var(--warn)', danger: 'var(--danger)', ok: 'var(--ok)' };
  const c = tones[tone] || tones.brand;
  return (
    <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, cursor: disabled ? 'not-allowed' : 'pointer', padding: label ? '7px 12px' : 0, borderRadius: 'var(--r-sm)', border: label ? `1px solid ${checked ? c : 'var(--border)'}` : 'none', background: label ? (checked ? `color-mix(in oklab, ${c} 10%, var(--bg-1))` : 'var(--bg-1)') : 'transparent', transition: 'all 120ms', fontSize: 13, color: checked ? c : 'var(--fg-2)', fontWeight: checked ? 600 : 500, userSelect: 'none', whiteSpace: 'nowrap', opacity: disabled ? 0.5 : 1 }}>
      <span style={{ width: 17, height: 17, borderRadius: 5, border: `1.5px solid ${checked ? c : 'var(--border-strong)'}`, background: checked ? c : 'transparent', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', transition: 'all 120ms', flexShrink: 0 }}>
        {checked && Icon.check({ size: 12, style: { color: '#fff' } })}
      </span>
      <input type="checkbox" checked={!!checked} onChange={e => onChange(e.target.checked)} disabled={disabled} style={{ display: 'none' }} />
      {label}
    </label>
  );
}

function Radio({ label, checked, onChange, name }) {
  return (
    <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontSize: 13.5, color: 'var(--fg-1)', userSelect: 'none' }}>
      <span style={{ width: 18, height: 18, borderRadius: '50%', border: `1.5px solid ${checked ? 'var(--brand)' : 'var(--border-strong)'}`, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', transition: 'all 120ms', flexShrink: 0 }}>
        {checked && <span style={{ width: 9, height: 9, borderRadius: '50%', background: 'var(--brand)' }} />}
      </span>
      <input type="radio" checked={checked} onChange={onChange} name={name} style={{ display: 'none' }} />
      {label}
    </label>
  );
}

/* ----------------------------- Segmented ----------------------------- */
function Segmented({ options, value, onChange, size = 'md' }) {
  const opts = options.map(o => typeof o === 'object' ? o : { value: o, label: o });
  const pad = size === 'sm' ? '5px 10px' : '7px 14px';
  return (
    <div style={{ display: 'inline-flex', gap: 3, padding: 3, background: 'var(--bg-2)', borderRadius: 'var(--r-sm)', border: '1px solid var(--border)' }}>
      {opts.map(o => {
        const active = o.value === value;
        return (
          <button key={o.value} type="button" onClick={() => onChange(o.value)}
            style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: pad, borderRadius: 6, border: 'none', background: active ? 'var(--bg-0)' : 'transparent', color: active ? 'var(--fg-1)' : 'var(--fg-2)', fontSize: size === 'sm' ? 12 : 13, fontWeight: active ? 600 : 500, cursor: 'pointer', fontFamily: 'inherit', boxShadow: active ? 'var(--shadow-sm)' : 'none', whiteSpace: 'nowrap', transition: 'all 120ms' }}>
            {o.icon && <span style={{ display: 'flex' }}>{typeof o.icon === 'function' ? o.icon({ size: 15 }) : o.icon}</span>}
            {o.label}
          </button>
        );
      })}
    </div>
  );
}

/* ----------------------------- Card ----------------------------- */
function Card({ title, subtitle, icon, actions, children, pad = 20, noBody, style, onClick, hover: hoverable }) {
  const [hover, setHover] = useState(false);
  return (
    <section onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{ background: 'var(--bg-0)', border: '1px solid var(--border)', borderRadius: 'var(--r-md)', overflow: 'hidden', boxShadow: hoverable && hover ? 'var(--shadow-md)' : 'var(--shadow-sm)', cursor: onClick ? 'pointer' : undefined, transition: 'box-shadow 150ms, transform 150ms', transform: hoverable && hover ? 'translateY(-2px)' : 'none', ...style }}>
      {(title || actions) && (
        <header style={{ padding: '14px 18px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 10 }}>
          {icon && <span style={{ color: 'var(--fg-2)', display: 'flex' }}>{typeof icon === 'function' ? icon({ size: 18 }) : icon}</span>}
          <div style={{ minWidth: 0, flex: 1 }}>
            {title && <h3 style={{ fontSize: 14.5, fontWeight: 600, color: 'var(--fg-1)' }}>{title}</h3>}
            {subtitle && <div style={{ fontSize: 12, color: 'var(--fg-3)', marginTop: 2 }}>{subtitle}</div>}
          </div>
          {actions && <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>{actions}</div>}
        </header>
      )}
      {noBody ? children : <div style={{ padding: pad }}>{children}</div>}
    </section>
  );
}

function Grid({ children, cols = 4, gap = 16, min }) {
  return <div style={{ display: 'grid', gridTemplateColumns: min ? `repeat(auto-fill, minmax(${min}px, 1fr))` : `repeat(${cols}, minmax(0, 1fr))`, gap }}>{children}</div>;
}

/* ----------------------------- Badge ----------------------------- */
function Badge({ children, tone = 'neutral', dot, size = 'md', icon }) {
  const tones = {
    neutral: { c: 'var(--fg-2)', bg: 'var(--bg-2)', bd: 'var(--border)' },
    ok: { c: 'var(--ok)', bg: 'var(--ok-soft)', bd: 'transparent' },
    warn: { c: 'var(--warn)', bg: 'var(--warn-soft)', bd: 'transparent' },
    danger: { c: 'var(--danger)', bg: 'var(--danger-soft)', bd: 'transparent' },
    info: { c: 'var(--info)', bg: 'var(--info-soft)', bd: 'transparent' },
    brand: { c: 'var(--brand)', bg: 'var(--brand-soft)', bd: 'transparent' },
  };
  const t = tones[tone] || tones.neutral;
  const sm = size === 'sm';
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: sm ? '2px 8px' : '3px 10px', borderRadius: 999, background: t.bg, color: t.c, border: `1px solid ${t.bd}`, fontSize: sm ? 11 : 12, fontWeight: 600, whiteSpace: 'nowrap', lineHeight: 1.5 }}>
      {dot && <span style={{ width: 6, height: 6, borderRadius: 6, background: t.c, flexShrink: 0 }} />}
      {icon && <span style={{ display: 'flex' }}>{typeof icon === 'function' ? icon({ size: 12 }) : icon}</span>}
      {children}
    </span>
  );
}

function Avatar({ name, size = 36, src, square }) {
  const initials = (name || '?').split(' ').filter(Boolean).slice(0, 2).map(w => w[0]).join('').toUpperCase();
  const hue = useMemo(() => { let h = 0; for (const ch of (name || '')) h = (h * 31 + ch.charCodeAt(0)) % 360; return h; }, [name]);
  return (
    <div style={{ width: size, height: size, borderRadius: square ? 'var(--r-sm)' : '50%', background: src ? `center/cover url(${src})` : `oklch(0.62 0.12 ${hue})`, color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: size * 0.38, fontWeight: 600, flexShrink: 0, letterSpacing: '0.01em' }}>
      {!src && initials}
    </div>
  );
}

/* ----------------------------- Tabs ----------------------------- */
function Tabs({ tabs, active, onChange, scroll }) {
  return (
    <div style={{ display: 'flex', gap: 2, borderBottom: '1px solid var(--border)', overflowX: scroll ? 'auto' : 'visible', scrollbarWidth: 'thin' }}>
      {tabs.map(t => {
        const on = active === t.id;
        return (
          <button key={t.id} onClick={() => onChange(t.id)}
            style={{ display: 'inline-flex', alignItems: 'center', gap: 7, padding: '11px 15px', border: 'none', borderBottom: `2px solid ${on ? 'var(--brand)' : 'transparent'}`, background: 'transparent', color: on ? 'var(--fg-1)' : 'var(--fg-2)', fontSize: 13.5, fontWeight: on ? 600 : 500, cursor: 'pointer', fontFamily: 'inherit', marginBottom: -1, whiteSpace: 'nowrap', transition: 'color 120ms' }}>
            {t.icon && <span style={{ display: 'flex', opacity: on ? 1 : 0.7 }}>{typeof t.icon === 'function' ? t.icon({ size: 16 }) : t.icon}</span>}
            {t.label}
            {t.badge != null && <span style={{ fontSize: 10.5, color: on ? 'var(--brand)' : 'var(--fg-3)', background: on ? 'var(--brand-soft)' : 'var(--bg-2)', borderRadius: 10, padding: '1px 7px', fontVariantNumeric: 'tabular-nums', fontWeight: 700 }}>{t.badge}</span>}
          </button>
        );
      })}
    </div>
  );
}

/* ----------------------------- Skeleton / loaders ----------------------------- */
function Skeleton({ w = '100%', h = 14, r = 6, style }) {
  return <div style={{ width: w, height: h, borderRadius: r, background: 'linear-gradient(90deg, var(--bg-3) 25%, var(--bg-2) 37%, var(--bg-3) 63%)', backgroundSize: '200% 100%', animation: 'ds-skeleton 1.4s ease infinite', ...style }} />;
}

function Spinner({ size = 18, color = 'var(--brand)' }) {
  return <span style={{ display: 'inline-block', width: size, height: size, border: `2px solid color-mix(in oklab, ${color} 25%, transparent)`, borderTopColor: color, borderRadius: '50%', animation: 'ds-spin 0.7s linear infinite' }} />;
}

/* ----------------------------- EmptyState ----------------------------- */
function EmptyState({ icon, title, desc, action, compact }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: compact ? '32px 20px' : '56px 24px', gap: 6 }}>
      <div style={{ width: 56, height: 56, borderRadius: 'var(--r-md)', background: 'var(--bg-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--fg-3)', marginBottom: 6 }}>
        {icon ? (typeof icon === 'function' ? icon({ size: 26 }) : icon) : Icon.box({ size: 26 })}
      </div>
      <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--fg-1)' }}>{title}</div>
      {desc && <div style={{ fontSize: 13, color: 'var(--fg-3)', maxWidth: 320 }}>{desc}</div>}
      {action && <div style={{ marginTop: 10 }}>{action}</div>}
    </div>
  );
}

function ErrorState({ title = 'Bir şeyler ters gitti', desc, onRetry, retryLabel = 'Tekrar dene' }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: '48px 24px', gap: 8 }}>
      <div style={{ width: 56, height: 56, borderRadius: 'var(--r-md)', background: 'var(--danger-soft)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--danger)' }}>{Icon.alert({ size: 26 })}</div>
      <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--fg-1)', marginTop: 4 }}>{title}</div>
      {desc && <div style={{ fontSize: 13, color: 'var(--fg-3)', maxWidth: 320 }}>{desc}</div>}
      {onRetry && <div style={{ marginTop: 8 }}><Button variant="secondary" icon={Icon.refresh} onClick={onRetry}>{retryLabel}</Button></div>}
    </div>
  );
}

/* ----------------------------- Progress ----------------------------- */
function Progress({ value, max = 100, tone = 'brand', height = 8, label }) {
  const pct = Math.min(100, Math.max(0, (value / max) * 100));
  const over = pct >= 90;
  const color = over ? 'var(--danger)' : tone === 'brand' ? 'var(--brand)' : `var(--${tone})`;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
      {label && <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, color: 'var(--fg-2)' }}><span>{label}</span><span className="tnum" style={{ fontWeight: 600, color: over ? 'var(--danger)' : 'var(--fg-1)' }}>{value}/{max}</span></div>}
      <div style={{ height, borderRadius: height, background: 'var(--bg-3)', overflow: 'hidden' }}>
        <div style={{ width: pct + '%', height: '100%', background: color, borderRadius: height, transition: 'width 400ms' }} />
      </div>
    </div>
  );
}

Object.assign(window, { Button, IconButton, Field, Input, Textarea, Select, Switch, Check, Radio, Segmented, Card, Grid, Badge, Avatar, Tabs, Skeleton, Spinner, EmptyState, ErrorState, Progress });
