// Shared primitives: buttons, inputs, star rating, avatars, cards

const Button = ({ children, variant='primary', size='md', leading, trailing, full, ...rest }) => {
  const styles = {
    primary: { background: 'var(--fg)', color: '#fff', border: '1px solid var(--fg)' },
    accent:  { background: 'var(--accent)', color: '#fff', border: '1px solid var(--accent)' },
    ghost:   { background: 'transparent', color: 'var(--fg)', border: '1px solid var(--border)' },
    soft:    { background: 'var(--surface-2)', color: 'var(--fg)', border: '1px solid transparent' },
    link:    { background: 'transparent', color: 'var(--accent)', border: '1px solid transparent', padding: '4px 2px' },
    danger:  { background: 'transparent', color: 'var(--bad)', border: '1px solid var(--border)' },
  };
  const sizes = {
    sm: { padding: '6px 10px', fontSize: 13, borderRadius: 8 },
    md: { padding: '9px 14px', fontSize: 14, borderRadius: 10 },
    lg: { padding: '12px 18px', fontSize: 15, borderRadius: 12 },
  };
  return (
    <button {...rest} style={{
      display: 'inline-flex', alignItems: 'center', gap: 8, fontWeight: 500,
      transition: 'transform .08s ease, background .15s ease, border-color .15s ease, opacity .15s ease',
      width: full ? '100%' : undefined,
      justifyContent: full ? 'center' : 'flex-start',
      ...styles[variant], ...sizes[size], ...(rest.style||{})
    }}
    onMouseDown={e => e.currentTarget.style.transform = 'scale(.985)'}
    onMouseUp={e => e.currentTarget.style.transform = 'scale(1)'}
    onMouseLeave={e => e.currentTarget.style.transform = 'scale(1)'}
    >
      {leading}{children}{trailing}
    </button>
  );
};

const Input = ({ leading, trailing, error, ...rest }) => {
  const [focused, setFocused] = React.useState(false);
  return (
    <label style={{
      display: 'flex', alignItems: 'center', gap: 10,
      background: 'var(--surface)',
      border: `1px solid ${error ? 'var(--bad)' : focused ? 'var(--fg)' : 'var(--border)'}`,
      borderRadius: 10, padding: '10px 12px',
      transition: 'border-color .15s ease, box-shadow .15s ease',
      boxShadow: focused ? '0 0 0 3px rgba(27,26,23,.06)' : 'none',
    }}>
      {leading && <span style={{ color: 'var(--fg-subtle)', display:'flex' }}>{leading}</span>}
      <input {...rest}
        onFocus={(e)=>{ setFocused(true); rest.onFocus?.(e); }}
        onBlur={(e)=>{ setFocused(false); rest.onBlur?.(e); }}
        style={{ flex:1, border:'none', outline:'none', background:'transparent', fontSize:14, color:'var(--fg)', padding:0, minWidth:0 }}
      />
      {trailing}
    </label>
  );
};

const Card = ({ children, style, padded=true, ...rest }) => (
  <div {...rest} style={{
    background: 'var(--surface)',
    border: '1px solid var(--border)',
    borderRadius: 'var(--radius-lg)',
    padding: padded ? 20 : 0,
    boxShadow: 'var(--shadow-sm)',
    ...style
  }}>{children}</div>
);

const Avatar = ({ name, emoji, size=32, color, ring }) => {
  const bg = color || 'var(--surface-2)';
  return (
    <div style={{
      width: size, height: size, borderRadius: size/2,
      background: bg, color: '#fff',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontSize: size*0.48, fontWeight: 600, flexShrink: 0,
      boxShadow: ring ? `0 0 0 2px var(--bg), 0 0 0 3px ${color||'var(--border-strong)'}` : 'none',
      border: color ? 'none' : '1px solid var(--border)',
    }}>
      {emoji ? <span style={{ filter: 'saturate(1.1)' }}>{emoji}</span> : (name||'?').slice(0,1).toUpperCase()}
    </div>
  );
};

const Pill = ({ children, tone='neutral', style }) => {
  const tones = {
    neutral: { bg: 'var(--surface-2)', fg: 'var(--fg-muted)' },
    accent:  { bg: 'var(--accent-soft)', fg: 'var(--accent-hover)' },
    good:    { bg: '#E5F0DE', fg: '#4A6E33' },
    warn:    { bg: '#FDEDD4', fg: '#8A5B14' },
    bad:     { bg: '#FBE1DA', fg: '#9A3218' },
  };
  const t = tones[tone];
  return (
    <span className="mono" style={{
      display:'inline-flex', alignItems:'center', gap: 6,
      background: t.bg, color: t.fg,
      fontSize: 11, fontWeight: 500, letterSpacing: '.02em',
      padding: '3px 8px', borderRadius: 999, textTransform: 'uppercase',
      ...style
    }}>{children}</span>
  );
};

const Divider = ({ v, style }) => (
  <div style={{
    background:'var(--border)',
    width: v ? 1 : '100%',
    height: v ? '100%' : 1,
    ...style
  }}/>
);

const SectionTitle = ({ eyebrow, title, action, style }) => (
  <div style={{ display:'flex', alignItems:'flex-end', justifyContent:'space-between', gap: 16, marginBottom: 14, ...style }}>
    <div>
      {eyebrow && <div className="mono" style={{ fontSize: 11, textTransform:'uppercase', letterSpacing:'.08em', color:'var(--fg-subtle)', marginBottom: 6 }}>{eyebrow}</div>}
      <h2 style={{ margin:0, fontSize: 20, fontWeight: 600, letterSpacing:'-.01em' }}>{title}</h2>
    </div>
    {action}
  </div>
);

// Modal wrapper
const Modal = ({ open, onClose, children, width=480 }) => {
  React.useEffect(()=>{
    if (!open) return;
    const h = (e)=> e.key === 'Escape' && onClose?.();
    window.addEventListener('keydown', h);
    return ()=> window.removeEventListener('keydown', h);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div onClick={onClose} style={{
      position:'fixed', inset: 0, background: 'rgba(20,18,14,.38)', backdropFilter:'blur(4px)',
      zIndex: 100, display:'flex', alignItems:'center', justifyContent:'center', padding: 24,
      animation: 'fadein .18s ease'
    }}>
      <style>{`@keyframes fadein{from{opacity:0}to{opacity:1}} @keyframes slideup{from{transform:translateY(12px);opacity:0}to{transform:translateY(0);opacity:1}}`}</style>
      <div onClick={e=>e.stopPropagation()} style={{
        background:'var(--surface)', borderRadius: 18, width: '100%', maxWidth: width,
        boxShadow: 'var(--shadow-lg)', border: '1px solid var(--border)',
        animation: 'slideup .24s cubic-bezier(.2,.8,.2,1)', overflow:'hidden'
      }}>
        {children}
      </div>
    </div>
  );
};

// Tooltip for chart cells
const HoverCard = ({ content, children }) => {
  const [show, setShow] = React.useState(false);
  const [pos, setPos] = React.useState({x:0,y:0});
  return (
    <span style={{ position:'relative', display:'inline-flex' }}
      onMouseEnter={e => {
        const r = e.currentTarget.getBoundingClientRect();
        setPos({ x: r.left + r.width/2, y: r.top });
        setShow(true);
      }}
      onMouseLeave={()=> setShow(false)}>
      {children}
      {show && (
        <div style={{
          position:'fixed', left: pos.x, top: pos.y - 10, transform: 'translate(-50%, -100%)',
          background: 'var(--fg)', color: '#fff', padding: '8px 10px', borderRadius: 8,
          fontSize: 12, whiteSpace: 'nowrap', pointerEvents:'none', zIndex: 50,
          boxShadow: 'var(--shadow-md)', animation:'fadein .1s ease'
        }}>
          {content}
          <div style={{ position:'absolute', left:'50%', bottom:-4, transform:'translateX(-50%) rotate(45deg)', width:8, height:8, background:'var(--fg)' }}/>
        </div>
      )}
    </span>
  );
};

const StarRating = ({ value, onChange, size=24, readOnly=false, showLabel=false, muted=false }) => {
  const [hover, setHover] = React.useState(0);
  const labels = ['', 'Очень плохо', 'Плохо', 'Так себе', 'Хорошо', 'Отлично'];
  const shown = hover || value || 0;
  return (
    <div style={{ display:'inline-flex', alignItems:'center', gap: 12 }}>
      <div style={{ display:'inline-flex', gap: size*0.18 }}
        onMouseLeave={()=> setHover(0)}>
        {[1,2,3,4,5].map(i => {
          const filled = i <= shown;
          return (
            <button key={i}
              disabled={readOnly}
              onMouseEnter={()=> !readOnly && setHover(i)}
              onClick={()=> !readOnly && onChange?.(i)}
              style={{
                background:'none', border:'none', padding:0, cursor: readOnly?'default':'pointer',
                color: filled ? (muted ? 'var(--fg-muted)' : 'var(--star)') : 'var(--border-strong)',
                transition: 'transform .12s ease, color .15s ease',
                transform: !readOnly && hover === i ? 'scale(1.12)' : 'scale(1)',
                lineHeight: 0,
              }}>
              <IconStar size={size} filled={filled} />
            </button>
          );
        })}
      </div>
      {showLabel && (
        <span className="mono" style={{ fontSize: 12, color: 'var(--fg-muted)', minWidth: 80 }}>
          {shown ? labels[shown] : '— без оценки'}
        </span>
      )}
    </div>
  );
};

Object.assign(window, { Button, Input, Card, Avatar, StarRating, Pill, Divider, SectionTitle, Modal, HoverCard });
