/* ============================================================
   Brite Bird Coach — shared components
   ============================================================ */

const toPascal = s => s.replace(/(^|-)(\w)/g, (_, __, c) => c.toUpperCase());

const Icon = ({ name, size = 20, color = 'currentColor', stroke = 2 }) => {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (ref.current && window.lucide) {
      ref.current.innerHTML = '';
      const data = window.lucide.icons[toPascal(name)] || window.lucide.icons.Circle;
      const el = window.lucide.createElement(data);
      el.setAttribute('width', size);
      el.setAttribute('height', size);
      el.setAttribute('stroke', color);
      el.setAttribute('stroke-width', stroke);
      ref.current.appendChild(el);
    }
  }, [name, size, color, stroke]);
  return <span ref={ref} style={{ display: 'inline-flex', lineHeight: 0, color }} />;
};

/* Pill — small inline label */
const Pill = ({ children, color = 'var(--bb-ink-10)', fg = 'var(--bb-plum)', icon, size = 'md' }) => {
  const pads = size === 'sm' ? '3px 9px' : '5px 11px';
  const fs = size === 'sm' ? 10 : 11;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      background: color, color: fg, borderRadius: 999,
      padding: pads, fontSize: fs, fontWeight: 700,
      letterSpacing: '0.06em', textTransform: 'uppercase',
      lineHeight: 1, whiteSpace: 'nowrap',
    }}>
      {icon && <Icon name={icon} size={11} stroke={2.4} />}
      {children}
    </span>
  );
};

/* Eyebrow — small caps label */
const Eyebrow = ({ children, color = 'var(--bb-pink)', style }) => (
  <div style={{
    fontSize: 10, fontWeight: 700, letterSpacing: '0.14em',
    textTransform: 'uppercase', color, ...style,
  }}>{children}</div>
);

/* ScoreRing — circular score 0-100 */
const ScoreRing = ({ score, size = 44, stroke = 4 }) => {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c - (score / 100) * c;
  const color = score >= 70 ? 'var(--bb-orange)' : score >= 50 ? 'var(--bb-pink)' : 'var(--bb-ink-40)';
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size}>
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="var(--bb-ink-10)" strokeWidth={stroke} />
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={color} strokeWidth={stroke}
          strokeDasharray={c} strokeDashoffset={off} strokeLinecap="round"
          transform={`rotate(-90 ${size / 2} ${size / 2})`} />
      </svg>
      <div style={{
        position: 'absolute', inset: 0, display: 'flex',
        alignItems: 'center', justifyContent: 'center',
        fontSize: size > 50 ? 16 : 12, fontWeight: 700, color: 'var(--bb-plum)',
      }}>{score}</div>
    </div>
  );
};

/* Avatar — initials in a soft tinted square */
const Avatar = ({ names, size = 38, tint }) => {
  const initials = names.map(n => n.split(' ').map(p => p[0]).join('').slice(0, 2)).join(' ').slice(0, 3);
  const tones = ['var(--bb-pink)', 'var(--bb-orange)', 'var(--bb-magenta)', 'var(--bb-tangerine)', 'var(--bb-yellow)'];
  const t = tint || tones[(initials.charCodeAt(0) || 0) % tones.length];
  return (
    <div style={{
      width: size, height: size, borderRadius: 14,
      background: t, color: 'white',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontWeight: 700, fontSize: size * 0.34, letterSpacing: 0.5,
      flex: 'none',
    }}>{initials}</div>
  );
};

/* Money — formatted currency, no cents */
const money = n => '$' + n.toLocaleString();

/* SectionLabel — used inside the deep-dive */
const SectionLabel = ({ children }) => (
  <div style={{
    fontSize: 11, fontWeight: 700, letterSpacing: '0.14em',
    textTransform: 'uppercase', color: 'var(--bb-ink-60)',
    margin: '20px 22px 8px',
  }}>{children}</div>
);

/* PrimaryButton — pink with the signature plum hard-drop */
const PrimaryButton = ({ children, onClick, icon, full = true, color = 'var(--bb-pink)' }) => (
  <button onClick={onClick} style={{
    width: full ? '100%' : 'auto',
    background: color, color: 'white',
    border: 0, borderRadius: 999,
    padding: '15px 22px',
    fontFamily: 'var(--font-family-base)',
    fontSize: 16, fontWeight: 700,
    letterSpacing: '0.01em',
    cursor: 'pointer',
    boxShadow: '0 6px 0 0 var(--bb-plum)',
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
    transition: 'transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out)',
  }} onPointerDown={e => { e.currentTarget.style.transform = 'translateY(3px)'; e.currentTarget.style.boxShadow = '0 3px 0 0 var(--bb-plum)'; }}
     onPointerUp={e => { e.currentTarget.style.transform = ''; e.currentTarget.style.boxShadow = '0 6px 0 0 var(--bb-plum)'; }}
     onPointerLeave={e => { e.currentTarget.style.transform = ''; e.currentTarget.style.boxShadow = '0 6px 0 0 var(--bb-plum)'; }}>
    {icon && <Icon name={icon} size={18} stroke={2.4} />}
    {children}
  </button>
);

/* GhostButton — outlined, plum */
const GhostButton = ({ children, onClick, icon, size = 'md' }) => {
  const pad = size === 'sm' ? '8px 14px' : '12px 18px';
  const fs = size === 'sm' ? 13 : 15;
  return (
    <button onClick={onClick} style={{
      background: 'transparent', color: 'var(--bb-plum)',
      border: '1.5px solid var(--bb-plum)', borderRadius: 999,
      padding: pad, fontFamily: 'var(--font-family-base)',
      fontSize: fs, fontWeight: 700, cursor: 'pointer',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
    }}>
      {icon && <Icon name={icon} size={15} stroke={2.4} />}
      {children}
    </button>
  );
};

/* IconButton — round, just an icon */
const IconButton = ({ icon, onClick, color = 'var(--bb-ink-10)', fg = 'var(--bb-plum)', size = 38 }) => (
  <button onClick={onClick} style={{
    width: size, height: size, borderRadius: 999,
    background: color, border: 0, color: fg,
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    cursor: 'pointer', flex: 'none',
  }}>
    <Icon name={icon} size={size * 0.45} stroke={2.2} />
  </button>
);

/* Enthusiasm dot — used in DM list */
const EnthDot = ({ enthusiasm }) => {
  const meta = ENTH_META[enthusiasm];
  return (
    <span style={{
      display: 'inline-block', width: 8, height: 8, borderRadius: 999,
      background: meta.color, marginRight: 6, verticalAlign: 'middle',
    }} />
  );
};

/* TopAppBar — Brite Bird wordmark-ish header inside the device */
const TopAppBar = ({ title, sub, right, onBack, dark = false, transparent = false }) => (
  <div style={{
    padding: '54px 20px 12px',
    background: transparent ? 'transparent' : (dark ? 'var(--bb-plum)' : 'transparent'),
    color: dark ? 'white' : 'var(--bb-plum)',
    display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 12,
    flex: 'none',
  }}>
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
      {onBack && (
        <button onClick={onBack} style={{
          width: 36, height: 36, borderRadius: 999, border: 0,
          background: dark ? 'rgba(255,255,255,0.12)' : 'var(--bb-ink-10)',
          color: dark ? 'white' : 'var(--bb-plum)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          cursor: 'pointer', flex: 'none',
        }}>
          <Icon name="chevron-left" size={20} stroke={2.4} />
        </button>
      )}
      <div style={{ minWidth: 0 }}>
        {sub && <div style={{
          fontSize: 11, fontWeight: 700, letterSpacing: '0.14em',
          textTransform: 'uppercase', color: dark ? 'rgba(255,255,255,0.7)' : 'var(--bb-pink)',
          marginBottom: 2,
        }}>{sub}</div>}
        <div style={{
          fontSize: 28, fontWeight: 700, letterSpacing: '-0.015em',
          lineHeight: 1.05, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
        }}>{title}</div>
      </div>
    </div>
    {right}
  </div>
);

/* SMS character counter — Twilio segment-cost protection.
   GSM-7 charset = 160/seg single, 153/seg multi.
   UCS-2 (em-dash, smart quotes, emoji) = 70/seg single, 67/seg multi.
   A rep editing a draft and accidentally pasting a smart quote can triple their segment count. */
const smsInfo = (text) => {
  const gsm7 = /^[ -~£¥à-ÿ\n\r\t]*$/.test(text);
  const len = text.length;
  const single = gsm7 ? 160 : 70;
  const multi  = gsm7 ? 153 : 67;
  const segs = len === 0 ? 0 : (len <= single ? 1 : Math.ceil(len / multi));
  return { len, segs, encoding: gsm7 ? 'GSM' : 'Unicode' };
};

const SmsCounter = ({ text, align = 'right' }) => {
  const { len, segs, encoding } = smsInfo(text);
  const tooLong = segs >= 3;
  const multi = segs >= 2;
  const color = tooLong ? 'var(--bb-magenta)' : multi ? 'var(--bb-orange)' : 'var(--bb-ink-40)';
  return (
    <div style={{
      fontSize: 10, fontWeight: 700, letterSpacing: '0.06em',
      color, marginTop: 6, textAlign: align,
      fontFeatureSettings: '"tnum"',
    }}>
      {len} · {segs} segment{segs === 1 ? '' : 's'}{encoding === 'Unicode' ? ' · unicode (½ rate)' : ''}
    </div>
  );
};

Object.assign(window, {
  Icon, Pill, Eyebrow, ScoreRing, Avatar, money, SectionLabel,
  PrimaryButton, GhostButton, IconButton, EnthDot, TopAppBar,
  smsInfo, SmsCounter,
});
