// ─── Chart Components (Canvas-based) ────────────────────────────────────────
// Exports: RadialGauge, LineChart, BarChart, DonutChart, SparkLine, HeatBar

const { useRef, useEffect, useState, useCallback } = React;

// ─── RadialGauge ─────────────────────────────────────────────────────────────
function RadialGauge({ value = 0, max = 100, label, unit = '%', color = '#00c8ff', size = 120, warning = 70, critical = 90 }) {
  const canvasRef = useRef(null);
  const pct = Math.min(value / max, 1);
  const c = pct * 100 >= critical ? '#ff2244' : pct * 100 >= warning ? '#ffd700' : color;

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    canvas.width = size * dpr; canvas.height = size * dpr;
    canvas.style.width = size + 'px'; canvas.style.height = size + 'px';
    ctx.scale(dpr, dpr);
    const cx = size / 2, cy = size / 2, r = size / 2 - 10;
    const startAngle = Math.PI * 0.75, endAngle = Math.PI * 2.25;
    ctx.clearRect(0, 0, size, size);

    // Track
    ctx.beginPath();
    ctx.arc(cx, cy, r, startAngle, endAngle);
    ctx.strokeStyle = 'rgba(0,100,150,0.25)';
    ctx.lineWidth = 6; ctx.lineCap = 'round'; ctx.stroke();

    // Tick marks
    for (let i = 0; i <= 10; i++) {
      const a = startAngle + (endAngle - startAngle) * (i / 10);
      const inner = r - 8, outer = r - 4;
      ctx.beginPath();
      ctx.moveTo(cx + Math.cos(a) * inner, cy + Math.sin(a) * inner);
      ctx.lineTo(cx + Math.cos(a) * outer, cy + Math.sin(a) * outer);
      ctx.strokeStyle = 'rgba(0,200,255,0.25)';
      ctx.lineWidth = 1; ctx.stroke();
    }

    // Fill arc
    if (pct > 0) {
      const fillEnd = startAngle + (endAngle - startAngle) * pct;
      ctx.beginPath();
      ctx.arc(cx, cy, r, startAngle, fillEnd);
      ctx.strokeStyle = c;
      ctx.lineWidth = 6; ctx.lineCap = 'round';
      ctx.shadowBlur = 10; ctx.shadowColor = c;
      ctx.stroke();
      ctx.shadowBlur = 0;
    }

    // Inner circle
    ctx.beginPath();
    ctx.arc(cx, cy, r - 14, 0, Math.PI * 2);
    ctx.fillStyle = 'rgba(0,5,15,0.8)'; ctx.fill();
    ctx.strokeStyle = 'rgba(0,200,255,0.08)'; ctx.lineWidth = 1; ctx.stroke();

    // Value text
    ctx.fillStyle = c;
    ctx.font = `bold ${size > 100 ? 22 : 16}px 'Share Tech Mono', monospace`;
    ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
    ctx.shadowBlur = 8; ctx.shadowColor = c;
    ctx.fillText(Math.round(value) + unit, cx, cy - 4);
    ctx.shadowBlur = 0;

    // Label
    if (label) {
      ctx.fillStyle = 'rgba(0,200,255,0.5)';
      ctx.font = `${size > 100 ? 8 : 7}px 'Share Tech Mono', monospace`;
      ctx.letterSpacing = '2px';
      ctx.fillText(label.toUpperCase(), cx, cy + (size > 100 ? 16 : 12));
    }
  }, [value, max, color, size, pct, c, label, unit]);

  return <canvas ref={canvasRef} style={{ display: 'block' }} />;
}

// ─── LineChart ───────────────────────────────────────────────────────────────
function LineChart({ data = [], color = '#00c8ff', height = 80, width = '100%', fill = true, label }) {
  const canvasRef = useRef(null);
  const containerRef = useRef(null);
  const [w, setW] = useState(300);

  useEffect(() => {
    if (!containerRef.current) return;
    const ro = new ResizeObserver(([e]) => setW(e.contentRect.width));
    ro.observe(containerRef.current);
    return () => ro.disconnect();
  }, []);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas || data.length < 2) return;
    const dpr = window.devicePixelRatio || 1;
    canvas.width = w * dpr; canvas.height = height * dpr;
    canvas.style.width = w + 'px'; canvas.style.height = height + 'px';
    const ctx = canvas.getContext('2d');
    ctx.scale(dpr, dpr);
    ctx.clearRect(0, 0, w, height);

    const min = Math.min(...data), max = Math.max(...data);
    const range = max - min || 1;
    const pad = 4;
    const pts = data.map((v, i) => ({
      x: pad + (i / (data.length - 1)) * (w - pad * 2),
      y: height - pad - ((v - min) / range) * (height - pad * 2)
    }));

    // Grid lines
    for (let i = 0; i <= 3; i++) {
      const y = pad + (i / 3) * (height - pad * 2);
      ctx.beginPath();
      ctx.moveTo(0, y); ctx.lineTo(w, y);
      ctx.strokeStyle = 'rgba(0,200,255,0.06)'; ctx.lineWidth = 1; ctx.stroke();
    }

    // Fill
    if (fill) {
      ctx.beginPath();
      ctx.moveTo(pts[0].x, height);
      pts.forEach(p => ctx.lineTo(p.x, p.y));
      ctx.lineTo(pts[pts.length - 1].x, height);
      ctx.closePath();
      const grad = ctx.createLinearGradient(0, 0, 0, height);
      grad.addColorStop(0, color + '30');
      grad.addColorStop(1, color + '00');
      ctx.fillStyle = grad; ctx.fill();
    }

    // Line
    ctx.beginPath();
    pts.forEach((p, i) => i === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y));
    ctx.strokeStyle = color; ctx.lineWidth = 1.5; ctx.lineJoin = 'round';
    ctx.shadowBlur = 6; ctx.shadowColor = color; ctx.stroke(); ctx.shadowBlur = 0;

    // Last point dot
    const last = pts[pts.length - 1];
    ctx.beginPath();
    ctx.arc(last.x, last.y, 3, 0, Math.PI * 2);
    ctx.fillStyle = color;
    ctx.shadowBlur = 8; ctx.shadowColor = color; ctx.fill(); ctx.shadowBlur = 0;
  }, [data, color, height, w, fill]);

  return (
    <div ref={containerRef} style={{ width, position: 'relative' }}>
      <canvas ref={canvasRef} style={{ display: 'block', width: '100%' }} />
    </div>
  );
}

// ─── BarChart ─────────────────────────────────────────────────────────────────
function BarChart({ data = [], color = '#00c8ff', height = 80 }) {
  const canvasRef = useRef(null);
  const containerRef = useRef(null);
  const [w, setW] = useState(300);

  useEffect(() => {
    if (!containerRef.current) return;
    const ro = new ResizeObserver(([e]) => setW(e.contentRect.width));
    ro.observe(containerRef.current);
    return () => ro.disconnect();
  }, []);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas || !data.length) return;
    const dpr = window.devicePixelRatio || 1;
    canvas.width = w * dpr; canvas.height = height * dpr;
    canvas.style.width = w + 'px'; canvas.style.height = height + 'px';
    const ctx = canvas.getContext('2d');
    ctx.scale(dpr, dpr);
    ctx.clearRect(0, 0, w, height);
    const max = Math.max(...data.map(d => d.value), 1);
    const gap = 2, bw = (w - gap * (data.length - 1)) / data.length;

    data.forEach((d, i) => {
      const bh = ((d.value / max) * (height - 14));
      const x = i * (bw + gap), y = height - bh - 10;
      const c = d.color || color;
      ctx.fillStyle = c + '20';
      ctx.fillRect(x, y, bw, bh);
      ctx.fillStyle = c;
      ctx.shadowBlur = 4; ctx.shadowColor = c;
      ctx.fillRect(x, y, bw, 1.5);
      ctx.shadowBlur = 0;
      if (d.label) {
        ctx.fillStyle = 'rgba(0,200,255,0.4)';
        ctx.font = `7px 'Share Tech Mono', monospace`;
        ctx.textAlign = 'center';
        ctx.fillText(d.label, x + bw / 2, height - 2);
      }
    });
  }, [data, color, height, w]);

  return (
    <div ref={containerRef} style={{ width: '100%' }}>
      <canvas ref={canvasRef} style={{ display: 'block', width: '100%' }} />
    </div>
  );
}

// ─── DonutChart ──────────────────────────────────────────────────────────────
function DonutChart({ segments = [], size = 100, label, value }) {
  const canvasRef = useRef(null);
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const dpr = window.devicePixelRatio || 1;
    canvas.width = size * dpr; canvas.height = size * dpr;
    canvas.style.width = size + 'px'; canvas.style.height = size + 'px';
    const ctx = canvas.getContext('2d');
    ctx.scale(dpr, dpr);
    ctx.clearRect(0, 0, size, size);
    const cx = size / 2, cy = size / 2, r = size / 2 - 8;
    const total = segments.reduce((s, d) => s + d.value, 0) || 1;
    let angle = -Math.PI / 2;
    segments.forEach(seg => {
      const sweep = (seg.value / total) * Math.PI * 2;
      ctx.beginPath();
      ctx.arc(cx, cy, r, angle, angle + sweep);
      ctx.arc(cx, cy, r - 12, angle + sweep, angle, true);
      ctx.closePath();
      ctx.fillStyle = seg.color + '30'; ctx.fill();
      ctx.strokeStyle = seg.color; ctx.lineWidth = 1.5;
      ctx.shadowBlur = 6; ctx.shadowColor = seg.color; ctx.stroke(); ctx.shadowBlur = 0;
      angle += sweep;
    });
    // Center
    ctx.beginPath(); ctx.arc(cx, cy, r - 14, 0, Math.PI * 2);
    ctx.fillStyle = 'rgba(0,5,15,0.9)'; ctx.fill();
    if (value !== undefined) {
      ctx.fillStyle = '#00c8ff';
      ctx.font = `bold ${size > 80 ? 18 : 13}px 'Share Tech Mono', monospace`;
      ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
      ctx.shadowBlur = 6; ctx.shadowColor = '#00c8ff';
      ctx.fillText(value, cx, cy - 4); ctx.shadowBlur = 0;
    }
    if (label) {
      ctx.fillStyle = 'rgba(0,200,255,0.45)';
      ctx.font = `7px 'Share Tech Mono', monospace`;
      ctx.fillText(label.toUpperCase(), cx, cy + (size > 80 ? 12 : 9));
    }
  }, [segments, size, label, value]);
  return <canvas ref={canvasRef} style={{ display: 'block' }} />;
}

// ─── HorizontalBar ────────────────────────────────────────────────────────────
function HorizontalBar({ value = 0, max = 100, color = '#00c8ff', height = 6, showLabel = true, label, sublabel }) {
  const pct = Math.min(value / max, 1) * 100;
  const c = pct >= 90 ? '#ff2244' : pct >= 70 ? '#ffd700' : color;
  return (
    <div style={{ marginBottom: 10 }}>
      {(label || sublabel) && (
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
          <span style={{ fontSize: 10, color: 'rgba(180,220,255,0.7)', fontFamily: "'Share Tech Mono',monospace", letterSpacing: '0.05em' }}>{label}</span>
          <span style={{ fontSize: 10, color: c, fontFamily: "'Share Tech Mono',monospace" }}>{sublabel || `${Math.round(pct)}%`}</span>
        </div>
      )}
      <div style={{ height, background: 'rgba(0,100,150,0.2)', position: 'relative', overflow: 'hidden' }}>
        <div style={{
          height: '100%', width: `${pct}%`,
          background: `linear-gradient(90deg, ${c}80, ${c})`,
          boxShadow: `0 0 8px ${c}60`,
          transition: 'width 0.8s cubic-bezier(0.4,0,0.2,1)',
        }} />
        <div style={{ position: 'absolute', inset: 0, background: 'repeating-linear-gradient(90deg,transparent,transparent 10px,rgba(0,0,0,0.15) 10px,rgba(0,0,0,0.15) 11px)' }} />
      </div>
    </div>
  );
}

// ─── SparkLine (inline tiny) ──────────────────────────────────────────────────
function SparkLine({ data = [], color = '#00c8ff', width = 60, height = 24 }) {
  const canvasRef = useRef(null);
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas || data.length < 2) return;
    const dpr = window.devicePixelRatio || 1;
    canvas.width = width * dpr; canvas.height = height * dpr;
    canvas.style.width = width + 'px'; canvas.style.height = height + 'px';
    const ctx = canvas.getContext('2d');
    ctx.scale(dpr, dpr);
    ctx.clearRect(0, 0, width, height);
    const min = Math.min(...data), max = Math.max(...data), range = max - min || 1;
    const pts = data.map((v, i) => ({ x: (i / (data.length - 1)) * width, y: height - ((v - min) / range) * height }));
    ctx.beginPath();
    pts.forEach((p, i) => i === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y));
    ctx.strokeStyle = color; ctx.lineWidth = 1.5; ctx.stroke();
  }, [data, color, width, height]);
  return <canvas ref={canvasRef} style={{ display: 'inline-block', verticalAlign: 'middle' }} />;
}

Object.assign(window, { RadialGauge, LineChart, BarChart, DonutChart, HorizontalBar, SparkLine });
