// case-viz.jsx — abstract animated visualization tiles for the cases section.
// Each tile is a tiny SVG/canvas scene that hints at the case domain without
// faking a real dashboard. Variants: 'flow', 'bars', 'orbit', 'pulse'.

function CaseViz({ variant, accent = "#00E6FF", accent2 = "#8B5CF6" }) {
  const ref = React.useRef(null);

  React.useEffect(() => {
    const cnv = ref.current;
    if (!cnv) return;
    const ctx = cnv.getContext("2d");
    let raf = 0;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    let W = 0, H = 0;
    const resize = () => {
      const r = cnv.getBoundingClientRect();
      W = r.width; H = r.height;
      cnv.width = W * dpr;
      cnv.height = H * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    };
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(cnv);

    const drawBars = (t) => {
      ctx.clearRect(0, 0, W, H);
      const cols = 28;
      const gap = 4;
      const cw = (W - gap * (cols - 1)) / cols;
      for (let i = 0; i < cols; i++) {
        const p = i / cols;
        const baseH =
          H * 0.2 +
          H * 0.55 * (0.5 + 0.5 * Math.sin(p * 6 + t * 0.001)) *
            (0.4 + 0.6 * Math.sin(p * 12 + t * 0.0006));
        const x = i * (cw + gap);
        const y = H - baseH;
        ctx.fillStyle = i % 5 === 0 ? accent : hexA2(accent, 0.4);
        ctx.fillRect(x, y, cw, baseH);
      }
    };

    const drawFlowCv = (t) => {
      ctx.clearRect(0, 0, W, H);
      for (let l = 0; l < 5; l++) {
        const yBase = H * (0.25 + 0.5 * (l / 4));
        ctx.beginPath();
        ctx.strokeStyle = l % 2 ? hexA2(accent2, 0.5) : hexA2(accent, 0.5);
        ctx.lineWidth = 1.2;
        for (let x = 0; x <= W; x += 4) {
          const y = yBase + Math.sin(x * 0.012 + t * 0.001 + l) * 10;
          if (x === 0) ctx.moveTo(x, y);
          else ctx.lineTo(x, y);
        }
        ctx.stroke();
      }
    };

    const drawOrbit = (t) => {
      ctx.clearRect(0, 0, W, H);
      const cx = W / 2, cy = H / 2;
      for (let r of [40, 65, 92, 120]) {
        ctx.strokeStyle = hexA2(accent, 0.15);
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.arc(cx, cy, r, 0, Math.PI * 2);
        ctx.stroke();
      }
      const nodes = 8;
      for (let i = 0; i < nodes; i++) {
        const a = (i / nodes) * Math.PI * 2 + t * 0.0004;
        const r = 60 + (i % 3) * 28;
        const x = cx + Math.cos(a) * r;
        const y = cy + Math.sin(a) * r;
        ctx.fillStyle = i % 2 ? accent : accent2;
        ctx.beginPath();
        ctx.arc(x, y, 3, 0, Math.PI * 2);
        ctx.fill();
      }
      ctx.fillStyle = accent;
      ctx.beginPath();
      ctx.arc(cx, cy, 5, 0, Math.PI * 2);
      ctx.fill();
    };

    const drawPulse = (t) => {
      ctx.clearRect(0, 0, W, H);
      const N = 80;
      ctx.beginPath();
      ctx.strokeStyle = accent;
      ctx.lineWidth = 1.5;
      for (let i = 0; i <= N; i++) {
        const x = (W * i) / N;
        let y = H * 0.5;
        const phase = (i / N) * 4;
        if (Math.abs(phase - 1.0) < 0.06) y -= H * 0.32;
        else if (Math.abs(phase - 1.15) < 0.05) y += H * 0.15;
        else if (Math.abs(phase - 2.3) < 0.06) y -= H * 0.26;
        else y += Math.sin(i * 0.5 + t * 0.005) * 1.5;
        if (i === 0) ctx.moveTo(x, y);
        else ctx.lineTo(x, y);
      }
      ctx.stroke();
    };

    const fn = { bars: drawBars, flow: drawFlowCv, orbit: drawOrbit, pulse: drawPulse }[variant] || drawBars;
    const loop = (t) => { fn(t); raf = requestAnimationFrame(loop); };
    raf = requestAnimationFrame(loop);
    return () => { cancelAnimationFrame(raf); ro.disconnect(); };
  }, [variant, accent, accent2]);

  return <canvas ref={ref} style={{ width: "100%", height: "100%", display: "block" }} />;
}

function hexA2(hex, a) {
  const h = String(hex).replace("#", "");
  const x = h.length === 3 ? h.replace(/./g, (c) => c + c) : h.padEnd(6, "0");
  const n = parseInt(x.slice(0, 6), 16);
  return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${a})`;
}

window.CaseViz = CaseViz;
