// ui.jsx — shared visual primitives (Button, Card, Badge, etc.)

const Button = ({ variant = 'primary', size = 'md', icon, iconRight, children, style = {}, disabled, onClick, ...rest }) => {
  const sizes = {
    sm: { padY: 6, padX: 12, font: 13, gap: 6, h: 32, r: 8 },
    md: { padY: 9, padX: 16, font: 14, gap: 8, h: 40, r: 10 },
    lg: { padY: 14, padX: 22, font: 16, gap: 10, h: 52, r: 14 },
    xl: { padY: 22, padX: 26, font: 18, gap: 12, h: 72, r: 18 },
  }[size];

  const variants = {
    primary: { bg: 'var(--accent)', color: '#fff', border: 'var(--accent)', hoverBg: 'var(--accent-deep)' },
    secondary: { bg: 'var(--panel)', color: 'var(--text)', border: 'var(--line-strong)', hoverBg: 'var(--panel-2)' },
    ghost:   { bg: 'transparent', color: 'var(--text)', border: 'transparent', hoverBg: 'rgba(0,0,0,0.04)' },
    danger:  { bg: 'var(--panel)', color: 'var(--bad)', border: 'var(--line-strong)', hoverBg: 'var(--bad-soft)' },
    success: { bg: 'var(--good)', color: '#fff', border: 'var(--good)', hoverBg: '#0F6644' },
    dark:    { bg: 'var(--text)', color: '#fff', border: 'var(--text)', hoverBg: '#000' },
  }[variant];

  const [hover, setHover] = useState(false);

  return (
    <button
      type="button"
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      disabled={disabled}
      style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        gap: sizes.gap,
        padding: `${sizes.padY}px ${sizes.padX}px`,
        height: sizes.h,
        fontSize: sizes.font, fontWeight: 600,
        background: disabled ? '#E5E7EB' : (hover ? variants.hoverBg : variants.bg),
        color: disabled ? '#9099A3' : variants.color,
        border: `1px solid ${disabled ? '#E5E7EB' : variants.border}`,
        borderRadius: sizes.r,
        cursor: disabled ? 'not-allowed' : 'pointer',
        transition: 'background 120ms ease, transform 80ms ease',
        userSelect: 'none',
        ...style,
      }}
      onMouseDown={(e) => !disabled && (e.currentTarget.style.transform = 'translateY(1px)')}
      onMouseUp={(e) => (e.currentTarget.style.transform = 'translateY(0)')}
      {...rest}
    >
      {icon && <span style={{ display: 'inline-flex' }}>{icon}</span>}
      {children}
      {iconRight && <span style={{ display: 'inline-flex' }}>{iconRight}</span>}
    </button>
  );
};

const Card = ({ children, padding = 16, style = {}, ...rest }) => (
  <div
    style={{
      background: 'var(--panel)',
      border: '1px solid var(--line)',
      borderRadius: 'var(--r-lg)',
      padding,
      ...style,
    }}
    {...rest}
  >
    {children}
  </div>
);

const Badge = ({ tone = 'neutral', icon, children, style = {} }) => {
  const tones = {
    neutral: { bg: '#EEF0F3', color: '#3A4451' },
    accent:  { bg: 'var(--accent-soft)', color: 'var(--accent-deep)' },
    good:    { bg: 'var(--good-soft)', color: 'var(--good)' },
    warn:    { bg: 'var(--warn-soft)', color: 'var(--warn)' },
    bad:     { bg: 'var(--bad-soft)', color: 'var(--bad)' },
    info:    { bg: 'var(--info-soft)', color: 'var(--info)' },
    dark:    { bg: '#222', color: '#fff' },
  }[tone];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '2px 8px', borderRadius: 999,
      background: tones.bg, color: tones.color,
      fontSize: 11.5, fontWeight: 600, letterSpacing: 0.2,
      textTransform: 'uppercase',
      ...style,
    }}>
      {icon}
      {children}
    </span>
  );
};

const StatusDot = ({ tone = 'good', pulse = false, size = 8 }) => {
  const color = ({ good: 'var(--good)', warn: 'var(--warn)', bad: 'var(--bad)', info: 'var(--info)', muted: '#9099A3' })[tone];
  return (
    <span style={{
      width: size, height: size, borderRadius: '50%', background: color,
      display: 'inline-block', flexShrink: 0,
      animation: pulse ? 'pulse-dot 1.6s ease-in-out infinite' : 'none',
      boxShadow: pulse ? `0 0 0 4px ${color}22` : 'none',
    }} />
  );
};

// Mark — logo block with company initials + tagline
const Mark = ({ size = 36, vertical = false, hideText = false }) => {
  const { tweaks } = useTweakValues();
  const fontSize = size * 0.42;
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 10 }}>
      <div style={{
        width: size, height: size, borderRadius: size * 0.22,
        background: 'var(--text)',
        color: '#fff',
        display: 'grid', placeItems: 'center',
        fontWeight: 700, fontSize, letterSpacing: 0.3,
        position: 'relative', overflow: 'hidden',
        flexShrink: 0,
      }}>
        <div style={{
          position: 'absolute', inset: 0, background: 'var(--accent)',
          clipPath: 'polygon(0 100%, 100% 100%, 100% 60%, 0 92%)',
          opacity: 0.95,
        }} />
        <span style={{ position: 'relative', zIndex: 1 }}>{tweaks.logoMark}</span>
      </div>
      {!hideText && (
        <div style={{ display: 'flex', flexDirection: vertical ? 'column' : 'row', alignItems: vertical ? 'flex-start' : 'baseline', gap: vertical ? 0 : 6 }}>
          <span style={{ fontSize: size * 0.42, fontWeight: 700, letterSpacing: -0.2, color: 'var(--text)' }}>
            {tweaks.companyName}
          </span>
          {tweaks.tagline && (
            <span style={{ fontSize: size * 0.28, color: 'var(--muted)', fontWeight: 500 }}>
              {tweaks.tagline}
            </span>
          )}
        </div>
      )}
    </div>
  );
};

// Avatar — initials disc
const Avatar = ({ name, initials, size = 36, tone = 'auto', ring = false }) => {
  const ini = initials || (name || '').split(/\s+/).map(s => s[0]).join('').slice(0, 2).toUpperCase();
  const colors = ['#1D6FB8', '#7C3AED', '#B45309', '#137C50', '#B42318', '#0E1418', '#7c2d12'];
  const idx = (ini.charCodeAt(0) + (ini.charCodeAt(1) || 0)) % colors.length;
  const bg = tone === 'auto' ? colors[idx] : tone;
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: bg, color: '#fff',
      display: 'grid', placeItems: 'center',
      fontSize: size * 0.38, fontWeight: 600,
      flexShrink: 0,
      boxShadow: ring ? `0 0 0 2px #fff, 0 0 0 4px var(--accent)` : 'none',
    }}>{ini}</div>
  );
};

// Field — input wrapper with label
const Field = ({ label, hint, error, children, required }) => (
  <label style={{ display: 'block', marginBottom: 14 }}>
    {label && (
      <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--text-2)', marginBottom: 6, letterSpacing: 0.2, textTransform: 'uppercase' }}>
        {label}{required && <span style={{ color: 'var(--bad)' }}> *</span>}
      </div>
    )}
    {children}
    {hint && !error && <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 4 }}>{hint}</div>}
    {error && <div style={{ fontSize: 12, color: 'var(--bad)', marginTop: 4 }}>{error}</div>}
  </label>
);

const Input = ({ style = {}, invalid, ...rest }) => (
  <input
    style={{
      width: '100%', padding: '10px 12px',
      fontSize: 14.5, color: 'var(--text)',
      background: 'var(--panel)',
      border: `1px solid ${invalid ? 'var(--bad)' : 'var(--line-strong)'}`,
      borderRadius: 8,
      outline: 'none',
      transition: 'border-color 120ms ease, box-shadow 120ms ease',
      ...style,
    }}
    onFocus={(e) => { e.target.style.borderColor = 'var(--accent)'; e.target.style.boxShadow = '0 0 0 3px rgba(229,91,19,0.15)'; }}
    onBlur={(e) => { e.target.style.borderColor = invalid ? 'var(--bad)' : 'var(--line-strong)'; e.target.style.boxShadow = 'none'; }}
    {...rest}
  />
);

const Textarea = ({ style = {}, invalid, rows = 3, ...rest }) => (
  <textarea
    rows={rows}
    style={{
      width: '100%', padding: '10px 12px',
      fontSize: 14.5, color: 'var(--text)',
      background: 'var(--panel)',
      border: `1px solid ${invalid ? 'var(--bad)' : 'var(--line-strong)'}`,
      borderRadius: 8, outline: 'none',
      fontFamily: 'inherit',
      resize: 'vertical',
      ...style,
    }}
    onFocus={(e) => { e.target.style.borderColor = 'var(--accent)'; e.target.style.boxShadow = '0 0 0 3px rgba(229,91,19,0.15)'; }}
    onBlur={(e) => { e.target.style.borderColor = invalid ? 'var(--bad)' : 'var(--line-strong)'; e.target.style.boxShadow = 'none'; }}
    {...rest}
  />
);

const Select = ({ options, value, onChange, style = {} }) => (
  <select
    value={value} onChange={e => onChange(e.target.value)}
    style={{
      width: '100%', padding: '10px 30px 10px 12px',
      fontSize: 14.5, color: 'var(--text)',
      background: 'var(--panel)',
      border: `1px solid var(--line-strong)`,
      borderRadius: 8, outline: 'none',
      appearance: 'none', WebkitAppearance: 'none',
      backgroundImage: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>")`,
      backgroundRepeat: 'no-repeat',
      backgroundPosition: 'right 10px center',
      cursor: 'pointer',
      ...style,
    }}
  >
    {options.map(o => (
      typeof o === 'string'
        ? <option key={o} value={o}>{o}</option>
        : <option key={o.value} value={o.value}>{o.label}</option>
    ))}
  </select>
);

// SegControl — segmented buttons
const SegControl = ({ options, value, onChange, fullWidth = false, size = 'md' }) => {
  const h = size === 'sm' ? 32 : 38;
  return (
    <div style={{
      display: 'inline-flex', background: '#EDF0F3', borderRadius: 10, padding: 3,
      width: fullWidth ? '100%' : 'auto',
    }}>
      {options.map(o => {
        const active = o.value === value;
        return (
          <button key={o.value} type="button" onClick={() => onChange(o.value)} style={{
            flex: fullWidth ? 1 : 'none',
            padding: `0 ${size === 'sm' ? 12 : 16}px`,
            height: h,
            border: 'none',
            background: active ? '#fff' : 'transparent',
            color: active ? 'var(--text)' : 'var(--muted)',
            fontWeight: active ? 600 : 500,
            fontSize: size === 'sm' ? 13 : 14,
            borderRadius: 8,
            cursor: 'pointer',
            boxShadow: active ? 'var(--shadow-sm)' : 'none',
            transition: 'all 140ms ease',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
          }}>
            {o.icon && <span style={{ display: 'inline-flex' }}>{o.icon}</span>}
            {o.label}
          </button>
        );
      })}
    </div>
  );
};

const Divider = ({ style = {} }) => (
  <div style={{ height: 1, background: 'var(--line)', margin: '12px 0', ...style }} />
);

const Sheet = ({ open, onClose, title, children, height = '70%' }) => {
  if (!open) return null;
  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 60,
      animation: 'fade-in 200ms ease-out both',
    }}>
      <div onClick={onClose} style={{
        position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.4)',
      }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        height,
        background: 'var(--panel)',
        borderTopLeftRadius: 24, borderTopRightRadius: 24,
        boxShadow: '0 -20px 40px rgba(0,0,0,0.18)',
        animation: 'slide-up 320ms cubic-bezier(.2,.7,.2,1) both',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 16px 8px' }}>
          <div style={{ fontWeight: 700, fontSize: 17 }}>{title}</div>
          <button onClick={onClose} style={{
            width: 32, height: 32, borderRadius: 16, border: 'none', background: '#EFF1F4',
            display: 'grid', placeItems: 'center', cursor: 'pointer',
          }}><IconClose size={16} /></button>
        </div>
        <div style={{ flex: 1, overflow: 'auto', padding: '4px 16px 24px' }}>{children}</div>
      </div>
    </div>
  );
};

const Modal = ({ open, onClose, title, children, width = 540, footer }) => {
  if (!open) return null;
  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 200,
      background: 'rgba(15,23,32,0.5)',
      display: 'grid', placeItems: 'center',
      padding: 20,
      animation: 'fade-in 180ms ease-out both',
    }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{
        background: 'var(--panel)', borderRadius: 16, width, maxWidth: '100%', maxHeight: '90vh',
        boxShadow: 'var(--shadow-lg)',
        display: 'flex', flexDirection: 'column',
        animation: 'slide-up 220ms ease-out both',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '18px 22px 10px' }}>
          <div style={{ fontWeight: 700, fontSize: 17 }}>{title}</div>
          <button onClick={onClose} style={{
            width: 32, height: 32, borderRadius: 16, border: 'none', background: '#EFF1F4',
            display: 'grid', placeItems: 'center', cursor: 'pointer',
          }}><IconClose size={16} /></button>
        </div>
        <div style={{ flex: 1, overflow: 'auto', padding: '6px 22px 18px' }}>{children}</div>
        {footer && <div style={{ padding: '12px 22px 18px', borderTop: '1px solid var(--line)' }}>{footer}</div>}
      </div>
    </div>
  );
};

// Toaster — top-right, listens to context queue
const Toaster = () => {
  const { toasts } = useApp();
  return (
    <div style={{
      position: 'fixed', top: 20, right: 20, zIndex: 9999,
      display: 'flex', flexDirection: 'column', gap: 8,
      pointerEvents: 'none',
    }}>
      {toasts.map(t => {
        const tones = {
          success: { bg: 'var(--good)', color: '#fff' },
          warn:    { bg: 'var(--warn)', color: '#fff' },
          info:    { bg: 'var(--text)', color: '#fff' },
        };
        const c = tones[t.kind] || tones.info;
        return (
          <div key={t.id} style={{
            padding: '12px 16px', minWidth: 240, maxWidth: 380,
            background: c.bg, color: c.color, borderRadius: 10,
            fontSize: 14, fontWeight: 500,
            boxShadow: 'var(--shadow-lg)',
            animation: 'toast-in 280ms ease-out both',
            pointerEvents: 'auto',
          }}>{t.text}</div>
        );
      })}
    </div>
  );
};

// SignaturePad — drawing canvas
const SignaturePad = ({ onChange, height = 160, color = '#0E1418' }) => {
  const ref = useRef(null);
  const drawing = useRef(false);
  const hasDrawn = useRef(false);

  useEffect(() => {
    const c = ref.current; if (!c) return;
    const dpr = window.devicePixelRatio || 1;
    const r = c.getBoundingClientRect();
    c.width = r.width * dpr; c.height = r.height * dpr;
    const ctx = c.getContext('2d');
    ctx.scale(dpr, dpr);
    ctx.strokeStyle = color; ctx.lineWidth = 2.2; ctx.lineCap = 'round'; ctx.lineJoin = 'round';
  }, [color]);

  const pos = (e) => {
    const r = ref.current.getBoundingClientRect();
    const t = e.touches ? e.touches[0] : e;
    return { x: t.clientX - r.left, y: t.clientY - r.top };
  };
  const start = (e) => { e.preventDefault(); drawing.current = true; const ctx = ref.current.getContext('2d'); const p = pos(e); ctx.beginPath(); ctx.moveTo(p.x, p.y); };
  const move = (e) => { if (!drawing.current) return; e.preventDefault(); const ctx = ref.current.getContext('2d'); const p = pos(e); ctx.lineTo(p.x, p.y); ctx.stroke(); hasDrawn.current = true; };
  const end = () => { drawing.current = false; if (hasDrawn.current && onChange) onChange(true); };
  const clear = () => {
    const c = ref.current; const ctx = c.getContext('2d');
    ctx.clearRect(0, 0, c.width, c.height);
    hasDrawn.current = false;
    if (onChange) onChange(false);
  };

  return (
    <div>
      <div style={{ position: 'relative', border: '1px dashed var(--line-strong)', borderRadius: 12, background: '#FAFBFC' }}>
        <canvas ref={ref}
          style={{ width: '100%', height, display: 'block', borderRadius: 12, cursor: 'crosshair', touchAction: 'none' }}
          onMouseDown={start} onMouseMove={move} onMouseUp={end} onMouseLeave={end}
          onTouchStart={start} onTouchMove={move} onTouchEnd={end}
        />
        <div style={{ position: 'absolute', bottom: 8, left: 14, fontSize: 11, color: 'var(--muted)', pointerEvents: 'none' }}>
          Sign here
        </div>
      </div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 6 }}>
        <button type="button" onClick={clear} style={{ background: 'none', border: 'none', color: 'var(--muted)', fontSize: 12.5, cursor: 'pointer', textDecoration: 'underline' }}>Clear</button>
      </div>
    </div>
  );
};

// Empty state
const Empty = ({ icon, title, hint }) => (
  <div style={{ textAlign: 'center', padding: '40px 20px', color: 'var(--muted)' }}>
    {icon && <div style={{ display: 'inline-flex', padding: 14, background: '#F1F3F6', borderRadius: 999, marginBottom: 12, color: 'var(--muted)' }}>{icon}</div>}
    <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--text-2)', marginBottom: 4 }}>{title}</div>
    {hint && <div style={{ fontSize: 13 }}>{hint}</div>}
  </div>
);

// useTweakValues — small hook for components to read from window.__currentTweaks
// (Bridge from App-level tweaks down without prop drilling)
function useTweakValues() {
  const [v, setV] = useState(() => window.__currentTweaks || window.__TWEAK_DEFAULTS);
  useEffect(() => {
    const handler = () => setV({ ...window.__currentTweaks });
    window.addEventListener('tweaks-changed', handler);
    return () => window.removeEventListener('tweaks-changed', handler);
  }, []);
  return { tweaks: v };
}

Object.assign(window, {
  Button, Card, Badge, StatusDot, Mark, Avatar,
  Field, Input, Textarea, Select, SegControl,
  Divider, Sheet, Modal, Toaster, SignaturePad, Empty,
  useTweakValues,
});
