// Pulse × 1990 — chart primitives (pure SVG, no deps)
// Theme-aware: uses CSS custom properties so the same components work in
// light + dark without re-renders. Brand colors resolved via getComputedStyle.

const cssVar = (name, defaultValue) => {
  if (typeof window === 'undefined') return defaultValue;
  const v = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
  return v || defaultValue;
};

// The brand red and the ink primary are our only two line/accent colors.
// Components read them on each render so they flip with the theme.
const useBrandColors = () => {
  const [, force] = React.useReducer(x => x + 1, 0);
  React.useEffect(() => {
    const onChange = () => force();
    window.addEventListener('pulse-theme-change', onChange);
    return () => window.removeEventListener('pulse-theme-change', onChange);
  }, []);
  return {
    red:    cssVar('--brand-500', '#EC2024'),
    ink:    cssVar('--text-primary', '#111111'),
    muted:  cssVar('--text-muted', '#6E6E6E'),
    grid:   cssVar('--border', '#E5E5E5'),
    track:  cssVar('--ink-100', '#F0F0F0'),
  };
};

const AreaChart = ({ data, keyA = 'views', keyB = 'engagement', height = 240, showLegend = true }) => {
  const c = useBrandColors();
  const w = 800, h = height, padL = 44, padR = 16, padT = 16, padB = 30;
  const safeData = data && data.length ? data : [{ label: 'Start', [keyA]: 0, [keyB]: 0 }, { label: 'Now', [keyA]: 0, [keyB]: 0 }];
  const maxA = Math.max(...safeData.map(d => d[keyA] || 0)) || 1;
  const maxB = Math.max(...safeData.map(d => d[keyB] || 0)) || 1;
  const x = i => padL + (i / (safeData.length - 1 || 1)) * (w - padL - padR);
  const yA = v => padT + (1 - v / maxA) * (h - padT - padB);
  const yB = v => padT + (1 - v / maxB) * (h - padT - padB);

  const pathA = safeData.map((d, i) => `${i === 0 ? 'M' : 'L'} ${x(i)} ${yA(d[keyA] || 0)}`).join(' ');
  const areaA = `${pathA} L ${x(safeData.length - 1)} ${h - padB} L ${x(0)} ${h - padB} Z`;
  const pathB = safeData.map((d, i) => `${i === 0 ? 'M' : 'L'} ${x(i)} ${yB(d[keyB] || 0)}`).join(' ');
  const gradId = 'gradViews_' + React.useId().replace(/:/g, '');

  return (
    <div style={{ position: 'relative' }}>
      {showLegend && (
        <div style={{ display: 'flex', gap: 16, position: 'absolute', top: -4, right: 0, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 700 }}>
          <span style={{ display: 'flex', alignItems: 'center', gap: 6, color: 'var(--text-secondary)' }}>
            <span style={{ width: 12, height: 2, background: c.red }}/> Views
          </span>
          <span style={{ display: 'flex', alignItems: 'center', gap: 6, color: 'var(--text-secondary)' }}>
            <span style={{ width: 12, height: 2, background: c.ink, borderStyle: 'dashed' }}/> Engagement
          </span>
        </div>
      )}
      <svg viewBox={`0 0 ${w} ${h}`} style={{ width: '100%', height: 'auto', display: 'block' }}>
        <defs>
          <linearGradient id={gradId} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={c.red} stopOpacity="0.22"/>
            <stop offset="100%" stopColor={c.red} stopOpacity="0"/>
          </linearGradient>
        </defs>

        {[0, 0.25, 0.5, 0.75, 1].map((t, i) => {
          const y = padT + t * (h - padT - padB);
          return <g key={i}>
            <line x1={padL} y1={y} x2={w - padR} y2={y} stroke={c.grid} strokeDasharray={i === 4 ? '0' : '2 4'}/>
            <text x={padL - 8} y={y + 4} textAnchor="end" fontSize="10" fill={c.muted} fontFamily="var(--font-mono)">
              {PULSE.fmt(Math.round(maxA * (1 - t)))}
            </text>
          </g>;
        })}

        {safeData.map((d, i) => {
          const step = Math.ceil(safeData.length / 8);
          if (i % step !== 0 && i !== safeData.length - 1) return null;
          return <text key={i} x={x(i)} y={h - 10} textAnchor="middle" fontSize="10" fill={c.muted} fontFamily="var(--font-mono)">{d.label}</text>;
        })}

        <path d={areaA} fill={`url(#${gradId})`}/>
        <path d={pathA} fill="none" stroke={c.red} strokeWidth="2" strokeLinejoin="round"/>
        <path d={pathB} fill="none" stroke={c.ink} strokeWidth="1.6" strokeLinejoin="round" strokeDasharray="4 3"/>

        {safeData.map((d, i) => (
          <circle key={i} cx={x(i)} cy={yA(d[keyA] || 0)} r="2.5" fill={c.red}/>
        ))}
      </svg>
    </div>
  );
};

const DonutChart = ({ data, size = 200, thickness = 28, centerLabel, centerValue }) => {
  const c = useBrandColors();
  const total = data.reduce((s, d) => s + d.value, 0) || 1;
  const cx = size / 2, cy = size / 2;
  const r = size / 2 - thickness / 2 - 2;
  let a0 = -Math.PI / 2;
  const arcs = data.map(d => {
    const frac = d.value / total;
    const a1 = a0 + frac * 2 * Math.PI;
    const large = frac > 0.5 ? 1 : 0;
    const x0 = cx + r * Math.cos(a0), y0 = cy + r * Math.sin(a0);
    const x1 = cx + r * Math.cos(a1), y1 = cy + r * Math.sin(a1);
    const path = `M ${x0} ${y0} A ${r} ${r} 0 ${large} 1 ${x1} ${y1}`;
    a0 = a1;
    return { ...d, path };
  });
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      <circle cx={cx} cy={cy} r={r} fill="none" stroke={c.track} strokeWidth={thickness}/>
      {arcs.map((a, i) => (
        <path key={i} d={a.path} fill="none" stroke={a.color} strokeWidth={thickness} strokeLinecap="butt"/>
      ))}
      {centerValue !== undefined && (
        <>
          <text x={cx} y={cy - 2} textAnchor="middle" fontSize="24" fontWeight="900" fill={c.ink} fontFamily="var(--font-display)" style={{ letterSpacing: '0em' }}>{centerValue}</text>
          <text x={cx} y={cy + 16} textAnchor="middle" fontSize="9" fill={c.muted} style={{ textTransform: 'uppercase', letterSpacing: '0.14em', fontWeight: 700 }}>{centerLabel}</text>
        </>
      )}
    </svg>
  );
};

// Horizontal progress bar — 1990 style: sharp corners, solid fills
const ProgressBar = ({ pct, committed, actual, label, color, height = 6 }) => {
  const c = useBrandColors();
  const clamped = Math.min(pct, 100);
  const over = pct > 100;
  const fill = color || (over ? c.ink : c.red);
  return (
    <div>
      {label && <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: 'var(--text-secondary)', marginBottom: 6, textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600 }}>
        <span>{label}</span>
        <span style={{ color: over ? c.ink : c.red, fontWeight: 800, fontFamily: 'var(--font-display)', letterSpacing: 0 }}>{pct}%</span>
      </div>}
      <div style={{ height, background: 'var(--ink-100)', borderRadius: 0, position: 'relative', overflow: 'hidden' }}>
        <div style={{
          width: `${clamped}%`, height: '100%',
          background: fill,
          transition: 'width 0.6s ease',
        }}/>
        {over && <div style={{ position: 'absolute', right: 0, top: 0, bottom: 0, width: 2, background: c.red }}/>}
      </div>
      {committed !== undefined && (
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: 'var(--text-muted)', marginTop: 4, fontFamily: 'var(--font-mono)', letterSpacing: '0.02em' }}>
          <span>{PULSE.fmt(actual)} actual</span>
          <span>{PULSE.fmt(committed)} committed</span>
        </div>
      )}
    </div>
  );
};

// Circular KPI ring
const KpiRing = ({ pct, size = 72, thickness = 7, color }) => {
  const c = useBrandColors();
  const r = size / 2 - thickness / 2;
  const circ = 2 * Math.PI * r;
  const clamped = Math.min(pct, 100);
  const strokeDasharray = `${(clamped / 100) * circ} ${circ}`;
  const over = pct > 100;
  // 1990 palette: over = ink (black/white depending on theme), under = red
  const col = color || (over ? c.ink : c.red);
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={c.track} strokeWidth={thickness}/>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={col} strokeWidth={thickness}
          strokeDasharray={strokeDasharray} strokeLinecap="butt" style={{ transition: 'stroke-dasharray 0.6s ease' }}/>
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center' }}>
        <div style={{ fontSize: size > 60 ? 14 : 11, fontWeight: 900, fontFamily: 'var(--font-display)', letterSpacing: 0 }}>{pct}%</div>
      </div>
    </div>
  );
};

// Sparkline
const Sparkline = ({ data, color, height = 32, width = 100, filled = true }) => {
  const c = useBrandColors();
  const stroke = color || c.red;
  const safeData = data && data.length ? data : [0, 0];
  const max = Math.max(...safeData), min = Math.min(...safeData);
  const range = max - min || 1;
  const x = i => (i / (safeData.length - 1 || 1)) * width;
  const y = v => height - ((v - min) / range) * height * 0.9 - 2;
  const path = safeData.map((v, i) => `${i === 0 ? 'M' : 'L'} ${x(i)} ${y(v)}`).join(' ');
  const area = `${path} L ${width} ${height} L 0 ${height} Z`;
  const id = 'spark_' + Math.random().toString(36).slice(2, 7);
  return (
    <svg width={width} height={height} style={{ display: 'block' }}>
      {filled && <>
        <defs>
          <linearGradient id={id} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={stroke} stopOpacity="0.28"/>
            <stop offset="100%" stopColor={stroke} stopOpacity="0"/>
          </linearGradient>
        </defs>
        <path d={area} fill={`url(#${id})`}/>
      </>}
      <path d={path} fill="none" stroke={stroke} strokeWidth="1.5" strokeLinejoin="round"/>
    </svg>
  );
};

// Platform icon badge — monochrome per 1990 brand. Red accent for TikTok's
// second letter so the icons stay legible without breaking palette.
const PlatformBadge = ({ platform, size = 22 }) => {
  const key = String(platform || '').toLowerCase();
  const label = key === 'tiktok' ? 'TikTok' : key === 'instagram' ? 'Instagram' : key === 'facebook' ? 'Facebook' : 'Social platform';
  const common = { width: size, height: size, borderRadius: 4, display: 'inline-grid', placeItems: 'center', flexShrink: 0 };
  const badgeProps = { title: label, 'aria-label': label };
  const icoSize = size * 0.62;
  if (key === 'tiktok') return (
    <div {...badgeProps} style={{ ...common, background: '#111111', border: '1px solid #111111' }}>
      <svg viewBox="0 0 24 24" width={icoSize} height={icoSize} fill="#FFFFFF">
        <path d="M16.6 5.82s.51.5 0 0A4.28 4.28 0 0 1 15.54 3h-3.09v12.4a2.59 2.59 0 0 1-2.59 2.5c-1.42 0-2.6-1.16-2.6-2.6 0-1.72 1.66-3.01 3.37-2.48V9.66c-3.45-.46-6.47 2.22-6.47 5.64 0 3.33 2.76 5.7 5.69 5.7 3.14 0 5.69-2.55 5.69-5.7V9.01a7.35 7.35 0 0 0 4.3 1.38V7.3s-1.88.09-3.24-1.48z"/>
      </svg>
    </div>
  );
  if (key === 'instagram') return (
    <div {...badgeProps} style={{ ...common, background: '#FFFFFF', border: '1.5px solid #111111' }}>
      <svg viewBox="0 0 24 24" width={icoSize} height={icoSize} fill="none" stroke="#111111" strokeWidth="2">
        <rect x="3" y="3" width="18" height="18" rx="5"/>
        <circle cx="12" cy="12" r="4"/>
        <circle cx="17.5" cy="6.5" r="0.8" fill="#EC2024" stroke="none"/>
      </svg>
    </div>
  );
  if (key === 'facebook') return (
    <div {...badgeProps} style={{ ...common, background: '#EC2024' }}>
      <svg viewBox="0 0 24 24" width={icoSize} height={icoSize} fill="#FFFFFF">
        <path d="M13.5 21v-8h2.6l.4-3h-3V8.1c0-.9.3-1.5 1.5-1.5H17V3.9c-.3 0-1.3-.1-2.4-.1-2.4 0-4 1.4-4 4.1V10H8v3h2.6v8h2.9z"/>
      </svg>
    </div>
  );
  return <div {...badgeProps} style={{ ...common, background: '#CCC' }}/>;
};

Object.assign(window, { AreaChart, DonutChart, ProgressBar, KpiRing, Sparkline, PlatformBadge });
