// ===== charts.jsx =====
// Custom SVG charts: Gauge, Radar, ModelBars, Hero data viz.

const { useState: useS, useEffect: useE, useRef: useR } = React;

// ---------- Gauge (large circular AIGC %) ----------
function Gauge({ value = 67, size = 240, label = 'AIGC 概率', sublabel = '', strokeWidth = 18 }) {
  const r = (size - strokeWidth) / 2;
  const c = 2 * Math.PI * r;
  const [drawn, setDrawn] = useS(0);
  useE(() => {
    let raf, start;
    const dur = 1400;
    const step = (ts) => {
      if (!start) start = ts;
      const t = Math.min(1, (ts - start) / dur);
      const e = 1 - Math.pow(1 - t, 3);
      setDrawn(value * e);
      if (t < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [value]);

  // color stops by value
  const color = drawn < 30 ? '#10B981' : drawn < 55 ? '#F59E0B' : drawn < 75 ? '#EF4444' : '#DC2626';
  const trackColor = '#E2E8F0';
  // 270° sweep from -135° to +135° (leave 90° gap at bottom)
  const SWEEP = 0.78; // 280deg portion of full circle
  const offset = c * (1 - (drawn / 100) * SWEEP);
  return (
    <div className="relative inline-block" style={{ width: size, height: size }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} className="-rotate-[126deg]">
        {/* track */}
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={trackColor} strokeWidth={strokeWidth}
                strokeDasharray={`${c * SWEEP} ${c}`} strokeLinecap="round" />
        {/* value */}
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={strokeWidth}
                strokeDasharray={`${c * SWEEP} ${c}`}
                strokeDashoffset={offset} strokeLinecap="round"
                style={{ transition: 'stroke .3s' }} />
        {/* tick marks */}
        {Array.from({ length: 11 }).map((_, i) => {
          const a = (-90 + (SWEEP * 360) * (i / 10)) * (Math.PI / 180);
          const ix = size/2 + Math.cos(a) * (r - strokeWidth/2 - 6);
          const iy = size/2 + Math.sin(a) * (r - strokeWidth/2 - 6);
          const ox = size/2 + Math.cos(a) * (r - strokeWidth/2 - 12);
          const oy = size/2 + Math.sin(a) * (r - strokeWidth/2 - 12);
          return <line key={i} x1={ix} y1={iy} x2={ox} y2={oy} stroke="#CBD5E1" strokeWidth="1" />;
        })}
      </svg>
      <div className="absolute inset-0 flex flex-col items-center justify-center">
        <div className="text-[11px] tracking-[0.18em] uppercase text-ink-500 mb-1">{label}</div>
        <div className="num text-[64px] leading-none font-bold text-navy-900">{Math.round(drawn)}<span className="text-[28px] text-ink-500 font-semibold align-top ml-0.5">%</span></div>
        {sublabel && <div className="text-[12px] text-ink-500 mt-2">{sublabel}</div>}
      </div>
    </div>
  );
}

// ---------- Radar (5-axis polygon) ----------
function Radar({ dims, size = 360 }) {
  const cx = size / 2, cy = size / 2;
  const radius = size * 0.36;
  const axes = MOCK.DIMENSIONS;
  const N = axes.length;
  const [t, setT] = useS(0);
  useE(() => {
    let raf, start;
    const dur = 1200;
    const step = (ts) => {
      if (!start) start = ts;
      const p = Math.min(1, (ts - start) / dur);
      setT(1 - Math.pow(1 - p, 3));
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, []);

  const pt = (i, v) => {
    const angle = (-Math.PI / 2) + (i * 2 * Math.PI / N);
    const r = radius * (v / 100);
    return [cx + Math.cos(angle) * r, cy + Math.sin(angle) * r];
  };
  const labelPt = (i) => {
    const angle = (-Math.PI / 2) + (i * 2 * Math.PI / N);
    const r = radius + 26;
    return [cx + Math.cos(angle) * r, cy + Math.sin(angle) * r, angle];
  };

  const poly = axes.map((a, i) => pt(i, dims[a.key] * t).join(',')).join(' ');

  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} className="overflow-visible">
      {/* rings */}
      {[20, 40, 60, 80, 100].map((g, i) => (
        <polygon key={i}
          points={axes.map((_, j) => pt(j, g).join(',')).join(' ')}
          fill="none"
          stroke={i === 4 ? '#CBD5E1' : '#E2E8F0'}
          strokeDasharray={i === 4 ? '0' : '0'}
        />
      ))}
      {/* axes */}
      {axes.map((_, i) => {
        const [x, y] = pt(i, 100);
        return <line key={i} x1={cx} y1={cy} x2={x} y2={y} stroke="#E2E8F0" />;
      })}
      {/* polygon */}
      <polygon points={poly} fill="rgba(37,99,235,0.16)" stroke="#2563EB" strokeWidth="1.8" />
      {/* dots */}
      {axes.map((a, i) => {
        const [x, y] = pt(i, dims[a.key] * t);
        return <circle key={i} cx={x} cy={y} r="3.5" fill="#2563EB" />;
      })}
      {/* labels */}
      {axes.map((a, i) => {
        const [lx, ly, angle] = labelPt(i);
        const align = Math.cos(angle) > 0.3 ? 'start' : Math.cos(angle) < -0.3 ? 'end' : 'middle';
        return (
          <g key={i}>
            <text x={lx} y={ly} textAnchor={align} dominantBaseline="middle"
                  fontSize="13" fill="#0F172A" fontWeight="600">{a.label}</text>
            <text x={lx} y={ly + 16} textAnchor={align} dominantBaseline="middle"
                  fontSize="11" fill="#64748B" className="tnum">{dims[a.key]}</text>
          </g>
        );
      })}
    </svg>
  );
}

// ---------- Model match bars ----------
function ModelBars({ models }) {
  return (
    <div className="space-y-3">
      {models.map((m, i) => {
        const intense = m.match >= 60;
        const mid = m.match >= 35 && m.match < 60;
        const barColor = intense ? '#EF4444' : mid ? '#F59E0B' : '#10B981';
        return (
          <div key={m.name} className="grid grid-cols-[160px_1fr_56px] items-center gap-3">
            <div className="text-[13.5px] text-ink-700 font-medium">{m.name}</div>
            <div className="relative h-2.5 bg-ink-100 rounded-full overflow-hidden">
              <div
                className="absolute inset-y-0 left-0 rounded-full"
                style={{
                  width: `${m.match}%`,
                  background: `linear-gradient(90deg, ${barColor}cc, ${barColor})`,
                  transition: `width 1.2s cubic-bezier(.22,.61,.36,1) ${i * 90}ms`,
                }}
              />
            </div>
            <div className="num text-right text-[13px] font-semibold text-navy-900">{m.match}<span className="text-ink-400">%</span></div>
          </div>
        );
      })}
    </div>
  );
}

// ---------- Hero data viz (decorative SVG with a 'live' probability curve) ----------
function HeroViz() {
  const [phase, setPhase] = useS(0);
  useE(() => {
    const id = setInterval(() => setPhase(p => (p + 1) % 1000), 50);
    return () => clearInterval(id);
  }, []);

  // Generate probability density curve
  const points = [];
  for (let i = 0; i <= 60; i++) {
    const x = i / 60;
    // Mixed bimodal: human (low) + AI (high)
    const human = 0.42 * Math.exp(-Math.pow((x - 0.28) / 0.13, 2));
    const ai    = 0.58 * Math.exp(-Math.pow((x - 0.72) / 0.10, 2));
    points.push({ x, y: human + ai, human, ai });
  }
  const W = 520, H = 360;
  const toX = (x) => 40 + x * (W - 80);
  const toY = (y) => H - 60 - y * (H - 100);

  const pathFor = (key) => points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${toX(p.x).toFixed(1)} ${toY(p[key]).toFixed(1)}`).join(' ');
  const areaFor = (key, color) => {
    const top = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${toX(p.x).toFixed(1)} ${toY(p[key]).toFixed(1)}`).join(' ');
    return `${top} L ${toX(1).toFixed(1)} ${toY(0).toFixed(1)} L ${toX(0).toFixed(1)} ${toY(0).toFixed(1)} Z`;
  };

  // Animated scan ratio
  const scanX = 0.05 + (phase % 200) / 200 * 0.9;
  const localProb = points.reduce((acc, p) => acc + Math.exp(-Math.pow((p.x - scanX) / 0.05, 2)) * p.y, 0) / 8;

  return (
    <div className="relative">
      <div className="absolute -top-10 -right-6 hidden lg:block">
        <Badge tone="navy" className="shadow-lg"><I.Sparkles size={12} /> 实时统计示意</Badge>
      </div>
      <svg viewBox={`0 0 ${W} ${H}`} className="w-full h-auto">
        <defs>
          <linearGradient id="g-human" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%"  stopColor="#10B981" stopOpacity="0.35" />
            <stop offset="100%" stopColor="#10B981" stopOpacity="0" />
          </linearGradient>
          <linearGradient id="g-ai" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%"  stopColor="#EF4444" stopOpacity="0.32" />
            <stop offset="100%" stopColor="#EF4444" stopOpacity="0" />
          </linearGradient>
          <pattern id="dots" patternUnits="userSpaceOnUse" width="16" height="16">
            <circle cx="1" cy="1" r="1" fill="#E2E8F0" />
          </pattern>
        </defs>

        {/* background */}
        <rect x="0" y="0" width={W} height={H} fill="white" />
        <rect x="40" y="20" width={W-80} height={H-80} fill="url(#dots)" opacity="0.6" />

        {/* axes */}
        <line x1="40" y1={H-60} x2={W-40} y2={H-60} stroke="#CBD5E1" strokeWidth="1" />
        <line x1="40" y1="20" x2="40" y2={H-60} stroke="#CBD5E1" strokeWidth="1" />
        {[0, 25, 50, 75, 100].map((tick) => (
          <g key={tick}>
            <line x1={toX(tick/100)} y1={H-60} x2={toX(tick/100)} y2={H-56} stroke="#94A3B8" />
            <text x={toX(tick/100)} y={H-44} fontSize="10" fill="#94A3B8" textAnchor="middle" className="tnum">{tick}%</text>
          </g>
        ))}
        <text x={W/2} y={H-22} fontSize="11" fill="#64748B" textAnchor="middle">AIGC 概率分布 · Perplexity × Burstiness</text>

        {/* curves */}
        <path d={areaFor('human', 'g-human')} fill="url(#g-human)" />
        <path d={areaFor('ai', 'g-ai')} fill="url(#g-ai)" />
        <path d={pathFor('human')} stroke="#10B981" strokeWidth="2" fill="none" strokeLinecap="round" />
        <path d={pathFor('ai')}    stroke="#EF4444" strokeWidth="2" fill="none" strokeLinecap="round" />

        {/* live scan */}
        <line x1={toX(scanX)} y1="22" x2={toX(scanX)} y2={H-60} stroke="#2563EB" strokeWidth="1.2" strokeDasharray="3 3" />
        <circle cx={toX(scanX)} cy={toY(localProb * 8)} r="4.5" fill="#2563EB" stroke="white" strokeWidth="2" />

        {/* annotations */}
        <g transform={`translate(${toX(0.22)}, ${toY(0.45)})`}>
          <rect x="-44" y="-26" width="88" height="22" rx="11" fill="white" stroke="#E2E8F0" />
          <circle cx="-32" cy="-15" r="3" fill="#10B981" />
          <text x="-24" y="-11" fontSize="11" fill="#0F172A">人类写作</text>
        </g>
        <g transform={`translate(${toX(0.72)}, ${toY(0.65)})`}>
          <rect x="-44" y="-28" width="88" height="22" rx="11" fill="white" stroke="#E2E8F0" />
          <circle cx="-32" cy="-17" r="3" fill="#EF4444" />
          <text x="-24" y="-13" fontSize="11" fill="#0F172A">AI 生成</text>
        </g>

        {/* corner readouts */}
        <g transform="translate(50, 40)">
          <text fontSize="10" fill="#64748B" letterSpacing="2">PERPLEXITY</text>
          <text y="20" fontSize="22" fill="#0F172A" fontWeight="700" className="tnum">68.4</text>
        </g>
        <g transform={`translate(${W-110}, 40)`}>
          <text fontSize="10" fill="#64748B" letterSpacing="2">BURSTINESS σ</text>
          <text y="20" fontSize="22" fill="#0F172A" fontWeight="700" className="tnum">12.7</text>
        </g>
      </svg>
    </div>
  );
}

// ---------- Process step indicator ----------
function StepNumber({ n }) {
  return (
    <div className="w-10 h-10 rounded-full bg-navy-900 text-white flex items-center justify-center font-semibold num text-[15px]">{n}</div>
  );
}

Object.assign(window, { Gauge, Radar, ModelBars, HeroViz, StepNumber });
