/* global React, fmt */
const { useState: useStateChart, useMemo: useMemoChart, useId: useIdChart } = React;

/* ============================================================
   LINE CHART · evolução mensal
   ============================================================ */
function LineChart({
  data = [],          // [{ label, value }]
  height = 220,
  formatY = fmt.k,
  formatTooltip = fmt.int,
  color,
  showArea = true,
}) {
  const uid = useIdChart();
  const W = 800, H = height, P = { t: 24, r: 16, b: 36, l: 48 };
  const innerW = W - P.l - P.r;
  const innerH = H - P.t - P.b;
  const c = color || 'var(--accent)';

  if (data.length < 2) {
    return <div style={{ color: 'var(--text-faint)', fontSize: 13 }}>Dados insuficientes.</div>;
  }

  const max = Math.max(...data.map(d => d.value));
  const min = Math.min(...data.map(d => d.value));
  const range = max - min || 1;
  const yMax = max + range * 0.15;
  const yMin = Math.max(0, min - range * 0.15);
  const yRange = yMax - yMin || 1;

  const x = (i) => P.l + (innerW * i) / (data.length - 1);
  const y = (v) => P.t + innerH - ((v - yMin) / yRange) * innerH;

  const path = data.map((d, i) => `${i === 0 ? 'M' : 'L'} ${x(i)} ${y(d.value)}`).join(' ');
  const areaPath = `${path} L ${x(data.length - 1)} ${P.t + innerH} L ${x(0)} ${P.t + innerH} Z`;

  // 4 ticks
  const ticks = [0, 1, 2, 3].map(i => yMin + (yRange * i) / 3);

  const [hover, setHover] = useStateChart(null);

  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height: 'auto', display: 'block' }} role="img">
      <defs>
        <linearGradient id={`grad-${uid}`} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={c} stopOpacity="0.28" />
          <stop offset="100%" stopColor={c} stopOpacity="0" />
        </linearGradient>
      </defs>

      {/* grid */}
      {ticks.map((t, i) => (
        <g key={i}>
          <line
            x1={P.l} x2={W - P.r}
            y1={y(t)} y2={y(t)}
            stroke="var(--chart-grid)"
            strokeWidth="1"
            strokeDasharray={i === 0 ? '0' : '2 4'}
          />
          <text
            x={P.l - 8} y={y(t) + 4}
            textAnchor="end" fontSize="11"
            fill="var(--text-faint)"
            fontFamily="'IBM Plex Sans', sans-serif"
            style={{ fontVariantNumeric: 'tabular-nums' }}
          >
            {formatY(t)}
          </text>
        </g>
      ))}

      {/* x labels */}
      {data.map((d, i) => (
        <text
          key={i}
          x={x(i)} y={H - P.b + 20}
          textAnchor="middle" fontSize="11"
          fill="var(--text-faint)"
          fontFamily="'IBM Plex Sans', sans-serif"
        >
          {d.label}
        </text>
      ))}

      {/* area */}
      {showArea && <path d={areaPath} fill={`url(#grad-${uid})`} />}

      {/* line */}
      <path d={path} fill="none" stroke={c} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />

      {/* points */}
      {data.map((d, i) => (
        <g key={i} onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)} style={{ cursor: 'pointer' }}>
          <circle cx={x(i)} cy={y(d.value)} r="12" fill="transparent" />
          <circle cx={x(i)} cy={y(d.value)} r={hover === i ? 5 : 3.5} fill="var(--bg-flat)" stroke={c} strokeWidth="2" />
        </g>
      ))}

      {/* tooltip */}
      {hover !== null && (() => {
        const d = data[hover];
        const tx = x(hover);
        const ty = y(d.value);
        const onRight = tx > W * 0.65;
        return (
          <g>
            <line x1={tx} x2={tx} y1={P.t} y2={P.t + innerH} stroke={c} strokeWidth="1" strokeDasharray="2 3" opacity="0.4" />
            <g transform={`translate(${onRight ? tx - 120 : tx + 12}, ${Math.max(P.t, ty - 30)})`}>
              <rect width="108" height="46" rx="8" fill="var(--bg-flat)" stroke="var(--border-strong)" />
              <text x="12" y="18" fontSize="10" fontWeight="500"
                fill="var(--text-faint)"
                fontFamily="'IBM Plex Sans', sans-serif"
                letterSpacing="0.1em"
                style={{ textTransform: 'uppercase' }}>
                {d.label}
              </text>
              <text x="12" y="36" fontSize="14" fontWeight="500"
                fill="var(--text)"
                fontFamily="'IBM Plex Sans', sans-serif"
                style={{ fontVariantNumeric: 'tabular-nums' }}>
                {formatTooltip(d.value)}
              </text>
            </g>
          </g>
        );
      })()}
    </svg>
  );
}

/* ============================================================
   BAR CHART · comparativos
   ============================================================ */
function BarChart({
  data = [],          // [{ label, value, highlight? }]
  height = 220,
  formatY = fmt.k,
  formatValue = fmt.int,
  color,
}) {
  const W = 800, H = height, P = { t: 24, r: 16, b: 36, l: 48 };
  const innerW = W - P.l - P.r;
  const innerH = H - P.t - P.b;
  const c = color || 'var(--accent)';

  if (!data.length) return null;

  const max = Math.max(...data.map(d => d.value));
  const yMax = max * 1.18 || 1;
  const ticks = [0, 1, 2, 3].map(i => (yMax * i) / 3);

  const gap = 16;
  const barW = (innerW - gap * (data.length - 1)) / data.length;
  const y = (v) => P.t + innerH - (v / yMax) * innerH;

  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height: 'auto', display: 'block' }} role="img">
      {ticks.map((t, i) => (
        <g key={i}>
          <line
            x1={P.l} x2={W - P.r}
            y1={y(t)} y2={y(t)}
            stroke="var(--chart-grid)" strokeWidth="1"
            strokeDasharray={i === 0 ? '0' : '2 4'}
          />
          <text x={P.l - 8} y={y(t) + 4}
            textAnchor="end" fontSize="11"
            fill="var(--text-faint)"
            fontFamily="'IBM Plex Sans', sans-serif"
            style={{ fontVariantNumeric: 'tabular-nums' }}>
            {formatY(t)}
          </text>
        </g>
      ))}

      {data.map((d, i) => {
        const bx = P.l + i * (barW + gap);
        const by = y(d.value);
        const bh = P.t + innerH - by;
        const isH = d.highlight;
        return (
          <g key={i}>
            <rect
              x={bx} y={by}
              width={barW} height={bh}
              rx="6"
              fill={isH ? c : 'var(--accent-soft)'}
              stroke={isH ? 'none' : 'var(--border-strong)'}
              strokeWidth="1"
            />
            <text
              x={bx + barW / 2} y={by - 8}
              textAnchor="middle" fontSize="12"
              fontWeight={isH ? 500 : 400}
              fill="var(--text)"
              fontFamily="'IBM Plex Sans', sans-serif"
              style={{ fontVariantNumeric: 'tabular-nums' }}>
              {formatValue(d.value)}
            </text>
            <text
              x={bx + barW / 2} y={H - P.b + 20}
              textAnchor="middle" fontSize="11"
              fill={isH ? 'var(--text)' : 'var(--text-faint)'}
              fontWeight={isH ? 500 : 400}
              fontFamily="'IBM Plex Sans', sans-serif">
              {d.label}
            </text>
          </g>
        );
      })}
    </svg>
  );
}

/* ============================================================
   FUNNEL CHART · alcance → engajamento → conversão
   ============================================================ */
function FunnelChart({ steps = [] }) {
  // steps: [{ label, value, hint? }]
  if (!steps.length) return null;
  const max = steps[0].value;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      {steps.map((s, i) => {
        const pct = (s.value / max) * 100;
        const dropPct = i > 0 ? ((steps[i - 1].value - s.value) / steps[i - 1].value) * 100 : null;
        return (
          <div key={i} style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 12 }}>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, minWidth: 0 }}>
                <span style={{
                  fontSize: 11, fontWeight: 500, letterSpacing: '0.1em',
                  textTransform: 'uppercase', color: 'var(--text-faint)',
                  fontVariantNumeric: 'tabular-nums',
                }}>
                  0{i + 1}
                </span>
                <span style={{ fontWeight: 500, fontSize: 14, color: 'var(--text)' }}>
                  {s.label}
                </span>
                {s.hint && (
                  <span style={{ fontSize: 12, color: 'var(--text-faint)' }}>
                    {s.hint}
                  </span>
                )}
              </div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, flexShrink: 0 }}>
                {dropPct !== null && (
                  <span style={{ fontSize: 12, color: 'var(--text-faint)', fontVariantNumeric: 'tabular-nums' }}>
                    {fmt.dec(100 - dropPct, 1)}% retenção
                  </span>
                )}
                <span style={{
                  fontWeight: 500, fontSize: 18, color: 'var(--text)',
                  fontVariantNumeric: 'tabular-nums',
                }}>
                  {fmt.int(s.value)}
                </span>
              </div>
            </div>
            <div style={{
              height: 14, background: 'var(--surface-soft)',
              borderRadius: 999, overflow: 'hidden',
              border: '1px solid var(--border)',
            }}>
              <div style={{
                height: '100%',
                width: pct + '%',
                background: `linear-gradient(90deg, var(--beza-purple), var(--beza-deep))`,
                opacity: 1 - i * 0.12,
                borderRadius: 999,
                transition: 'width var(--t-slow) var(--ease-out)',
              }} />
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ============================================================
   SPARKBAR · barra horizontal compacta (top posts engagement)
   ============================================================ */
function Sparkbar({ value, max, color, label }) {
  const pct = (value / max) * 100;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <div style={{
        flex: 1, height: 6, background: 'var(--surface-soft)',
        borderRadius: 999, overflow: 'hidden',
      }}>
        <div style={{
          height: '100%', width: pct + '%',
          background: color || 'var(--accent)',
          borderRadius: 999,
        }} />
      </div>
      <span style={{
        fontSize: 12, color: 'var(--text-muted)', fontVariantNumeric: 'tabular-nums',
        minWidth: 50, textAlign: 'right',
      }}>
        {label}
      </span>
    </div>
  );
}

Object.assign(window, { LineChart, BarChart, FunnelChart, Sparkbar });
