// HeroCanvas — drifting bioelectric cell field
// Three treatments: "cells", "field", "mycelium"
const { useEffect: useEffectH, useRef: useRefH } = React;

function HeroCanvas({ treatment = "cells", dark = false, accent = "rust" }) {
  const canvasRef = useRefH(null);
  const rafRef = useRefH(0);

  useEffectH(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    let W, H, DPR;
    const resize = () => {
      DPR = Math.min(window.devicePixelRatio || 1, 2);
      W = canvas.clientWidth;
      H = canvas.clientHeight;
      canvas.width = W * DPR;
      canvas.height = H * DPR;
      ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
    };
    resize();
    window.addEventListener("resize", resize);

    // accent colors in rgba for canvas
    const palette = {
      rust:    { a: [192, 96, 64],   b: [120, 150, 110] },
      moss:    { a: [92, 150, 108],  b: [180, 150, 90] },
      iris:    { a: [130, 105, 200], b: [200, 120, 170] },
      saffron: { a: [220, 170, 70],  b: [200, 110, 70] },
    }[accent] || { a: [192, 96, 64], b: [120, 150, 110] };

    const bg = dark ? [28, 26, 24] : [247, 243, 236];
    const ink = dark ? [235, 230, 220] : [60, 50, 44];

    // Cells with soft membranes, drifting
    const N = treatment === "cells" ? 22 : treatment === "mycelium" ? 16 : 14;
    const cells = Array.from({ length: N }, () => ({
      x: Math.random() * W,
      y: Math.random() * H,
      r: 40 + Math.random() * 140,
      vx: (Math.random() - 0.5) * 0.12,
      vy: (Math.random() - 0.5) * 0.12,
      phase: Math.random() * Math.PI * 2,
      freq: 0.3 + Math.random() * 0.5,
      color: Math.random() > 0.5 ? palette.a : palette.b,
      deform: 0.1 + Math.random() * 0.25,
    }));

    // Mycelium nodes
    const nodes = Array.from({ length: 40 }, () => ({
      x: Math.random() * W, y: Math.random() * H,
      vx: (Math.random() - 0.5) * 0.3, vy: (Math.random() - 0.5) * 0.3,
    }));

    let t0 = performance.now();

    const draw = () => {
      const t = (performance.now() - t0) / 1000;

      // soft background tint
      ctx.fillStyle = `rgba(${bg[0]},${bg[1]},${bg[2]},1)`;
      ctx.fillRect(0, 0, W, H);

      if (treatment === "cells") {
        // subtle field gradient wash
        const g = ctx.createRadialGradient(W * 0.3, H * 0.5, 20, W * 0.5, H * 0.5, Math.max(W, H) * 0.7);
        g.addColorStop(0, `rgba(${palette.a[0]},${palette.a[1]},${palette.a[2]},${dark ? 0.08 : 0.05})`);
        g.addColorStop(1, `rgba(${bg[0]},${bg[1]},${bg[2]},0)`);
        ctx.fillStyle = g;
        ctx.fillRect(0, 0, W, H);

        ctx.globalCompositeOperation = dark ? "lighter" : "multiply";
        cells.forEach((c) => {
          c.x += c.vx; c.y += c.vy;
          if (c.x < -c.r) c.x = W + c.r;
          if (c.x > W + c.r) c.x = -c.r;
          if (c.y < -c.r) c.y = H + c.r;
          if (c.y > H + c.r) c.y = -c.r;

          // deforming blob
          const steps = 42;
          ctx.beginPath();
          for (let i = 0; i <= steps; i++) {
            const a = (i / steps) * Math.PI * 2;
            const wob =
              Math.sin(a * 3 + t * c.freq + c.phase) * c.deform * c.r * 0.6 +
              Math.cos(a * 5 + t * c.freq * 0.7) * c.deform * c.r * 0.3;
            const rr = c.r + wob;
            const x = c.x + Math.cos(a) * rr;
            const y = c.y + Math.sin(a) * rr;
            if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
          }
          ctx.closePath();
          const rg = ctx.createRadialGradient(c.x, c.y, 0, c.x, c.y, c.r * 1.2);
          const alpha = dark ? 0.22 : 0.14;
          rg.addColorStop(0, `rgba(${c.color[0]},${c.color[1]},${c.color[2]},${alpha})`);
          rg.addColorStop(1, `rgba(${c.color[0]},${c.color[1]},${c.color[2]},0)`);
          ctx.fillStyle = rg;
          ctx.fill();

          // membrane line
          ctx.strokeStyle = `rgba(${c.color[0]},${c.color[1]},${c.color[2]},${dark ? 0.35 : 0.25})`;
          ctx.lineWidth = 0.6;
          ctx.stroke();

          // nucleus
          ctx.beginPath();
          const nr = c.r * 0.12 * (1 + Math.sin(t * 1.4 + c.phase) * 0.2);
          ctx.arc(c.x + Math.sin(t * 0.5 + c.phase) * 4, c.y + Math.cos(t * 0.4 + c.phase) * 4, nr, 0, Math.PI * 2);
          ctx.fillStyle = `rgba(${c.color[0]},${c.color[1]},${c.color[2]},${dark ? 0.55 : 0.35})`;
          ctx.fill();
        });
        ctx.globalCompositeOperation = "source-over";
      }

      if (treatment === "field") {
        // Bioelectric isoline field
        const cols = 60, rows = 34;
        const cw = W / cols, ch = H / rows;
        for (let i = 0; i < cols; i++) {
          for (let j = 0; j < rows; j++) {
            const x = i * cw + cw / 2;
            const y = j * ch + ch / 2;
            const v =
              Math.sin(x * 0.01 + t * 0.5) +
              Math.cos(y * 0.012 - t * 0.4) +
              Math.sin((x + y) * 0.008 + t * 0.2);
            const mag = (v + 3) / 6;
            const col = mag > 0.55 ? palette.a : palette.b;
            const op = Math.pow(Math.abs(v), 1.4) * (dark ? 0.08 : 0.05);
            ctx.fillStyle = `rgba(${col[0]},${col[1]},${col[2]},${op})`;
            ctx.fillRect(x - cw / 2, y - ch / 2, cw, ch);
          }
        }
        // isolines
        ctx.strokeStyle = `rgba(${ink[0]},${ink[1]},${ink[2]},${dark ? 0.12 : 0.09})`;
        ctx.lineWidth = 0.5;
        for (let k = 0; k < 8; k++) {
          ctx.beginPath();
          for (let x = 0; x <= W; x += 4) {
            const y =
              H / 2 +
              Math.sin(x * 0.008 + t * 0.3 + k * 0.5) * 80 +
              Math.sin(x * 0.02 + t * 0.6 + k) * 30 +
              (k - 4) * H * 0.08;
            if (x === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
          }
          ctx.stroke();
        }
      }

      if (treatment === "mycelium") {
        // Drifting nodes with thread connections
        nodes.forEach((n) => {
          n.x += n.vx; n.y += n.vy;
          if (n.x < 0 || n.x > W) n.vx *= -1;
          if (n.y < 0 || n.y > H) n.vy *= -1;
        });
        // Connections
        ctx.strokeStyle = `rgba(${palette.a[0]},${palette.a[1]},${palette.a[2]},${dark ? 0.3 : 0.22})`;
        ctx.lineWidth = 0.5;
        for (let i = 0; i < nodes.length; i++) {
          for (let j = i + 1; j < nodes.length; j++) {
            const dx = nodes[i].x - nodes[j].x;
            const dy = nodes[i].y - nodes[j].y;
            const d = Math.hypot(dx, dy);
            if (d < 220) {
              const a = (1 - d / 220) * (dark ? 0.4 : 0.25);
              ctx.strokeStyle = `rgba(${palette.a[0]},${palette.a[1]},${palette.a[2]},${a})`;
              // curved thread
              const mx = (nodes[i].x + nodes[j].x) / 2 + Math.sin(t + i) * 10;
              const my = (nodes[i].y + nodes[j].y) / 2 + Math.cos(t + j) * 10;
              ctx.beginPath();
              ctx.moveTo(nodes[i].x, nodes[i].y);
              ctx.quadraticCurveTo(mx, my, nodes[j].x, nodes[j].y);
              ctx.stroke();
            }
          }
        }
        // Nodes
        nodes.forEach((n, k) => {
          const r = 2 + Math.sin(t * 1.2 + k) * 1;
          ctx.beginPath();
          ctx.arc(n.x, n.y, r + 3, 0, Math.PI * 2);
          ctx.fillStyle = `rgba(${palette.a[0]},${palette.a[1]},${palette.a[2]},${dark ? 0.15 : 0.1})`;
          ctx.fill();
          ctx.beginPath();
          ctx.arc(n.x, n.y, r, 0, Math.PI * 2);
          ctx.fillStyle = `rgba(${palette.a[0]},${palette.a[1]},${palette.a[2]},0.9)`;
          ctx.fill();
        });
      }

      // subtle grain
      if (!dark) {
        ctx.fillStyle = "rgba(0,0,0,0.015)";
        for (let i = 0; i < 80; i++) {
          ctx.fillRect(Math.random() * W, Math.random() * H, 1, 1);
        }
      }

      rafRef.current = requestAnimationFrame(draw);
    };
    draw();

    return () => {
      cancelAnimationFrame(rafRef.current);
      window.removeEventListener("resize", resize);
    };
  }, [treatment, dark, accent]);

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

window.HeroCanvas = HeroCanvas;
