// Canvas 3D-ish ambient background — wireframe sphere + particle field
// Replaces Spline embed since we can't load that exact scene
function HeroBackground() {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    let raf;
    let mouseX = 0, mouseY = 0;
    let dpr = Math.min(window.devicePixelRatio || 1, 2);

    function resize() {
      const r = canvas.getBoundingClientRect();
      canvas.width = r.width * dpr;
      canvas.height = r.height * dpr;
      ctx.scale(dpr, dpr);
    }
    resize();
    const onResize = () => {
      dpr = Math.min(window.devicePixelRatio || 1, 2);
      ctx.setTransform(1, 0, 0, 1, 0, 0);
      resize();
    };
    window.addEventListener("resize", onResize);

    const onMove = (e) => {
      const r = canvas.getBoundingClientRect();
      mouseX = (e.clientX - r.left) / r.width - 0.5;
      mouseY = (e.clientY - r.top) / r.height - 0.5;
    };
    window.addEventListener("mousemove", onMove);

    // Build sphere wireframe (lat/long)
    const LAT = 18, LON = 28;
    const verts = [];
    for (let i = 0; i <= LAT; i++) {
      const theta = (i / LAT) * Math.PI;
      const sinT = Math.sin(theta), cosT = Math.cos(theta);
      const row = [];
      for (let j = 0; j <= LON; j++) {
        const phi = (j / LON) * Math.PI * 2;
        row.push({ x: sinT * Math.cos(phi), y: cosT, z: sinT * Math.sin(phi) });
      }
      verts.push(row);
    }

    // Floating particles in 3D
    const particles = [];
    for (let i = 0; i < 90; i++) {
      const u = Math.random() * Math.PI * 2;
      const v = Math.acos(2 * Math.random() - 1);
      const r = 1.6 + Math.random() * 1.6;
      particles.push({
        x: r * Math.sin(v) * Math.cos(u),
        y: r * Math.cos(v),
        z: r * Math.sin(v) * Math.sin(u),
        s: 0.3 + Math.random() * 1.3,
        phase: Math.random() * Math.PI * 2,
      });
    }

    let t0 = performance.now();
    function frame(now) {
      const t = (now - t0) / 1000;
      const w = canvas.width / dpr;
      const h = canvas.height / dpr;

      ctx.fillStyle = "hsl(0 0% 6%)";
      ctx.fillRect(0, 0, w, h);

      const cx = w * 0.68 + mouseX * 20;
      const cy = h * 0.5 + mouseY * 20;
      const radius = Math.min(w, h) * 0.36;

      const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, radius * 2.4);
      grad.addColorStop(0, "hsl(119 99% 46% / 0.10)");
      grad.addColorStop(0.5, "hsl(119 99% 46% / 0.03)");
      grad.addColorStop(1, "hsl(119 99% 46% / 0)");
      ctx.fillStyle = grad;
      ctx.fillRect(0, 0, w, h);

      const ry = t * 0.18 + mouseX * 0.3;
      const rx = Math.sin(t * 0.13) * 0.25 + mouseY * 0.2;
      const cosRy = Math.cos(ry), sinRy = Math.sin(ry);
      const cosRx = Math.cos(rx), sinRx = Math.sin(rx);

      const focal = radius * 1.6;

      function project(v) {
        const pulse = 1 + Math.sin(t * 1.2) * 0.025;
        let x = v.x * pulse;
        let y = v.y * pulse;
        let z = v.z * pulse;
        const x1 = x * cosRy + z * sinRy;
        const z1 = -x * sinRy + z * cosRy;
        const y1 = y * cosRx - z1 * sinRx;
        const z2 = y * sinRx + z1 * cosRx;

        const depth = focal / (focal / radius + z2 * radius * 0.4);
        return {
          x: cx + x1 * radius * depth / (focal / radius),
          y: cy + y1 * radius * depth / (focal / radius),
          z: z2,
        };
      }

      for (let i = 1; i < LAT; i++) {
        ctx.beginPath();
        for (let j = 0; j <= LON; j++) {
          const p = project(verts[i][j]);
          if (j === 0) ctx.moveTo(p.x, p.y);
          else ctx.lineTo(p.x, p.y);
        }
        const alpha = 0.06 + (Math.sin(i / LAT * Math.PI) * 0.15);
        ctx.strokeStyle = `hsl(119 99% 46% / ${alpha})`;
        ctx.lineWidth = 1;
        ctx.stroke();
      }

      for (let j = 0; j < LON; j += 1) {
        ctx.beginPath();
        for (let i = 0; i <= LAT; i++) {
          const p = project(verts[i][j]);
          if (i === 0) ctx.moveTo(p.x, p.y);
          else ctx.lineTo(p.x, p.y);
        }
        const alpha = 0.06 + Math.abs(Math.cos((j / LON) * Math.PI * 2 + t * 0.2)) * 0.16;
        ctx.strokeStyle = `hsl(119 99% 56% / ${alpha})`;
        ctx.lineWidth = 1;
        ctx.stroke();
      }

      for (let i = 0; i <= LAT; i += 2) {
        for (let j = 0; j <= LON; j += 2) {
          const p = project(verts[i][j]);
          if (p.z > 0) {
            const s = 0.4 + p.z * 1.6;
            ctx.fillStyle = `hsl(119 99% 60% / ${0.25 + p.z * 0.5})`;
            ctx.beginPath();
            ctx.arc(p.x, p.y, s, 0, Math.PI * 2);
            ctx.fill();
          }
        }
      }

      for (const pt of particles) {
        const p = project(pt);
        const tw = 0.5 + Math.sin(t * 2 + pt.phase) * 0.5;
        const sz = pt.s * (0.6 + p.z * 0.8) * tw;
        if (sz <= 0) continue;
        ctx.fillStyle = `hsl(119 99% 70% / ${0.25 + p.z * 0.4})`;
        ctx.beginPath();
        ctx.arc(p.x, p.y, sz, 0, Math.PI * 2);
        ctx.fill();
      }

      ctx.fillStyle = "hsl(119 99% 46% / 0.04)";
      const yScan = (Math.sin(t * 0.3) * 0.5 + 0.5) * h;
      ctx.fillRect(0, yScan, w, 1);

      raf = requestAnimationFrame(frame);
    }
    raf = requestAnimationFrame(frame);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("resize", onResize);
      window.removeEventListener("mousemove", onMove);
    };
  }, []);

  return <canvas ref={ref} aria-hidden="true" />;
}

window.HeroBackground = HeroBackground;
