// ============================================================
// SocialPulse — Shared UI Components
// ============================================================
const { useState, useRef, useEffect, useMemo } = React;

// ---- Sparkline SVG ----
function Sparkline({ data, width=80, height=24, color='var(--lime)', strokeWidth=1.5, fill=false }) {
  if (!data || data.length < 2) return null;
  const max = Math.max(...data);
  const min = Math.min(...data);
  const range = max - min || 1;
  const pad = 2;
  const pts = data.map((v, i) => {
    const x = (i / (data.length - 1)) * width;
    const y = pad + (1 - (v - min) / range) * (height - pad * 2);
    return `${x},${y}`;
  }).join(' ');

  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} style={{display:'block'}}>
      {fill && (
        <polygon
          points={`0,${height} ${pts} ${width},${height}`}
          fill={color} opacity="0.12"
        />
      )}
      <polyline points={pts} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

// ---- Platform badge ----
function PlatformBadge({ platform }) {
  const isFb = platform === 'fb';
  const platformBadgeStyles = {
    display:'inline-flex', alignItems:'center',
    padding:'1px 6px', borderRadius:'var(--r-xs)',
    fontFamily:'var(--font-mono)', fontSize:9, fontWeight:700,
    color:'#fff', letterSpacing:'.04em',
    background: isFb ? 'var(--fb)' : 'linear-gradient(135deg,#f09433,#dc2743,#bc1888)',
  };
  return <span style={platformBadgeStyles}>{isFb ? 'FB' : 'IG'}</span>;
}

// ---- Severity badge ----
function SevBadge({ severity, children }) {
  const colors = {
    high:  { bg:'var(--red-soft)', color:'var(--red)', border:'rgba(255,85,119,.3)' },
    warn:  { bg:'var(--amber-soft)', color:'var(--amber)', border:'rgba(245,179,36,.3)' },
    med:   { bg:'var(--amber-soft)', color:'var(--amber)', border:'rgba(245,179,36,.3)' },
    info:  { bg:'var(--indigo-soft)', color:'var(--indigo2)', border:'rgba(99,102,241,.3)' },
    good:  { bg:'var(--green-soft)', color:'var(--green)', border:'rgba(45,212,138,.28)' },
  };
  const c = colors[severity] || colors.info;
  const sevBadgeStyle = {
    display:'inline-flex', alignItems:'center', gap:5,
    padding:'2px 8px', borderRadius:999,
    fontFamily:'var(--font-mono)', fontSize:10, fontWeight:600,
    textTransform:'uppercase', letterSpacing:'.06em',
    background:c.bg, color:c.color, border:`1px solid ${c.border}`,
  };
  return <span style={sevBadgeStyle}>{children}</span>;
}

// ---- Kicker label (mono uppercase with line) ----
function Kicker({ children }) {
  const kickerStyle = {
    fontFamily:'var(--font-mono)', fontSize:11, color:'var(--text3)',
    textTransform:'uppercase', letterSpacing:'.14em',
    display:'flex', alignItems:'center', gap:12,
    marginBottom:'var(--sp-3)',
  };
  return (
    <div style={kickerStyle}>
      {children}
      <span style={{flex:1,height:1,background:'linear-gradient(90deg,var(--line),transparent)'}}/>
    </div>
  );
}

// ---- Delta badge (green up / red down) ----
function Delta({ value, suffix='%' }) {
  const isPos = value >= 0;
  const deltaStyle = {
    fontFamily:'var(--font-mono)', fontSize:12, fontWeight:600,
    color: isPos ? 'var(--lime)' : 'var(--red)',
    marginLeft:6,
  };
  return <span style={deltaStyle}>{isPos?'+':''}{value}{suffix}</span>;
}

// ---- Empty state ----
function EmptyState({ title, desc }) {
  return (
    <div style={{textAlign:'center',padding:'60px 20px',color:'var(--text2)'}}>
      <div style={{fontSize:16,fontWeight:600,color:'var(--text)',marginBottom:4}}>{title}</div>
      {desc && <div style={{fontSize:13}}>{desc}</div>}
    </div>
  );
}

// ---- Brand avatar (initial-based) ----
function BrandAvatar({ name, color, size=32 }) {
  const initial = name ? name.charAt(0) : '?';
  const avatarStyle = {
    width:size, height:size, borderRadius:'var(--r-md)',
    background: `linear-gradient(135deg, ${color || 'var(--panel2)'}, ${color || 'var(--panel2)'}88)`,
    display:'flex', alignItems:'center', justifyContent:'center',
    fontSize: size * 0.4, fontWeight:700, color:'#fff',
    flexShrink:0,
  };
  return <div style={avatarStyle}>{initial}</div>;
}

// ---- Tooltip on hover ----
function HoverCard({ children, content }) {
  const [show, setShow] = useState(false);
  return (
    <span style={{position:'relative',display:'inline-flex'}}
      onMouseEnter={()=>setShow(true)} onMouseLeave={()=>setShow(false)}>
      {children}
      {show && (
        <div style={{
          position:'absolute', bottom:'calc(100% + 6px)', left:'50%', transform:'translateX(-50%)',
          background:'var(--panel2)', border:'1px solid var(--line)', borderRadius:'var(--r-md)',
          padding:'6px 10px', fontSize:12, color:'var(--text)', whiteSpace:'nowrap', zIndex:50,
          boxShadow:'var(--shadow-md)', pointerEvents:'none',
        }}>{content}</div>
      )}
    </span>
  );
}

// ---- Shared formatters ----
function fmtK(n) {
  n = Number(n) || 0;
  if (n >= 10000) return (n / 10000).toFixed(1) + '萬';
  if (n >= 1000) return (n / 1000).toFixed(1) + 'K';
  return String(n);
}

function fmtPct(n, digits = 0) {
  return (n >= 0 ? '+' : '') + Number(n).toFixed(digits) + '%';
}

function fmtDate(s) {
  if (!s) return '';
  return s.slice(0, 10);
}

// ---- Toast system (module-level singleton) ----
const _toastListeners = new Set();
let _toastSeq = 0;
function spToast(text, kind = 'ok', ttl = 3000) {
  const id = ++_toastSeq;
  const t = { id, text, kind, ttl };
  _toastListeners.forEach(fn => { try { fn({ type: 'add', toast: t }); } catch {} });
  setTimeout(() => {
    _toastListeners.forEach(fn => { try { fn({ type: 'remove', id }); } catch {} });
  }, ttl);
}

function ToastHost() {
  const [list, setList] = useState([]);
  useEffect(() => {
    const fn = (ev) => {
      if (ev.type === 'add') setList(l => [...l, ev.toast]);
      else setList(l => l.filter(x => x.id !== ev.id));
    };
    _toastListeners.add(fn);
    return () => _toastListeners.delete(fn);
  }, []);
  if (!list.length) return null;
  return (
    <div style={{position:'fixed',bottom:24,right:24,zIndex:9999,display:'flex',flexDirection:'column',gap:8,maxWidth:360}}>
      {list.map(t => (
        <div key={t.id} style={{
          padding:'10px 14px',borderRadius:'var(--r-md)',fontSize:13,fontWeight:500,
          color:'#fff',boxShadow:'var(--shadow-md,0 6px 18px rgba(0,0,0,.3))',
          background: t.kind === 'err' ? 'var(--red,#ff5577)' : t.kind === 'warn' ? 'var(--amber,#f5b324)' : 'var(--green,#2dd48a)',
          animation: 'spToastIn .2s ease-out',
        }}>{t.text}</div>
      ))}
      <style>{`@keyframes spToastIn{from{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}`}</style>
    </div>
  );
}

Object.assign(window, {
  Sparkline, PlatformBadge, SevBadge, Kicker, Delta,
  EmptyState, BrandAvatar, HoverCard,
  fmtK, fmtPct, fmtDate,
  spToast, ToastHost,
});
