"use client";

import { useEffect, useRef } from "react";

/**
 * Full-page fixed canvas that draws a distorted grid background.
 * The grid warps toward the mouse cursor like a gravitational lens /
 * spacetime distortion — grid lines curve inward, intersections glow,
 * and a soft mass-glow follows the cursor.
 */
export default function GridCanvas() {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    let raf: number;

    // Smoothed mouse position (lerped toward target)
    let mx = -3000;
    let my = -3000;
    // Raw target from events
    let tx = -3000;
    let ty = -3000;

    const GRID     = 64;   // px between grid lines
    const SIGMA    = 190;  // radius of distortion effect (px)
    const STRENGTH = 52;   // max pixel pull toward cursor

    // ── resize ───────────────────────────────────────────────────────────────
    const resize = () => {
      canvas.width  = window.innerWidth;
      canvas.height = window.innerHeight;
    };
    resize();
    window.addEventListener("resize", resize);

    // ── mouse tracking (global so it works across the whole page) ────────────
    const onPointerMove  = (e: PointerEvent) => { if (e.pointerType === "mouse") { tx = e.clientX; ty = e.clientY; } };
    const onPointerLeave = (e: PointerEvent) => { if (e.pointerType === "mouse") { tx = -3000; ty = -3000; } };
    window.addEventListener("pointermove", onPointerMove);
    document.documentElement.addEventListener("pointerleave", onPointerLeave);

    // ── touch tracking (mobile) ───────────────────────────────────────────────
    const onTouch = (e: TouchEvent) => {
      const t = e.touches[0];
      if (t) { tx = t.clientX; ty = t.clientY; }
    };
    window.addEventListener("touchstart", onTouch, { passive: true });
    window.addEventListener("touchmove", onTouch, { passive: true });

    // ── displacement: pull a point (px,py) toward the cursor ─────────────────
    const warp = (px: number, py: number): [number, number] => {
      const dx = px - mx;
      const dy = py - my;
      const d2 = dx * dx + dy * dy;
      if (d2 < 1) return [px, py];
      const d = Math.sqrt(d2);
      const f = STRENGTH * Math.exp(-d2 / (2 * SIGMA * SIGMA));
      return [px - (dx / d) * f, py - (dy / d) * f];
    };

    // ── main draw loop ────────────────────────────────────────────────────────
    const draw = () => {
      // Smooth-lerp mouse position (feels weighty / spacetime-like)
      mx += (tx - mx) * 0.065;
      my += (ty - my) * 0.065;

      const W = canvas.width;
      const H = canvas.height;
      const active = mx > -2000;

      ctx.clearRect(0, 0, W, H);

      // ── horizontal grid lines ─────────────────────────────────────────────
      for (let gy = 0; gy <= H + GRID; gy += GRID) {
        const lineDist = active ? Math.abs(gy - my) : 9999;
        const lift     = active ? Math.max(0, 1 - lineDist / (SIGMA * 1.4)) : 0;
        ctx.beginPath();
        let first = true;
        for (let x = 0; x <= W; x += 5) {
          const [wx, wy] = active ? warp(x, gy) : [x, gy];
          first ? ctx.moveTo(wx, wy) : ctx.lineTo(wx, wy);
          first = false;
        }
        ctx.strokeStyle = `rgba(200,169,110,${0.048 + lift * 0.12})`;
        ctx.lineWidth   = 0.5 + lift * 0.55;
        ctx.stroke();
      }

      // ── vertical grid lines ───────────────────────────────────────────────
      for (let gx = 0; gx <= W + GRID; gx += GRID) {
        const lineDist = active ? Math.abs(gx - mx) : 9999;
        const lift     = active ? Math.max(0, 1 - lineDist / (SIGMA * 1.4)) : 0;
        ctx.beginPath();
        let first = true;
        for (let y = 0; y <= H; y += 5) {
          const [wx, wy] = active ? warp(gx, y) : [gx, y];
          first ? ctx.moveTo(wx, wy) : ctx.lineTo(wx, wy);
          first = false;
        }
        ctx.strokeStyle = `rgba(200,169,110,${0.048 + lift * 0.12})`;
        ctx.lineWidth   = 0.5 + lift * 0.55;
        ctx.stroke();
      }

      // ── intersection dots (lensed stars) ─────────────────────────────────
      if (active) {
        const cullR2 = (SIGMA * 2.2) * (SIGMA * 2.2);
        for (let gx = 0; gx <= W + GRID; gx += GRID) {
          for (let gy = 0; gy <= H + GRID; gy += GRID) {
            const dx = gx - mx;
            const dy = gy - my;
            const d2 = dx * dx + dy * dy;
            if (d2 > cullR2) continue;

            const [wx, wy] = warp(gx, gy);
            const intensity = Math.exp(-d2 / (2 * SIGMA * SIGMA * 0.35));

            // outer halo
            ctx.beginPath();
            ctx.arc(wx, wy, 1.5 + intensity * 2, 0, Math.PI * 2);
            ctx.fillStyle = `rgba(200,169,110,${0.1 + intensity * 0.5})`;
            ctx.fill();

            // bright core for very close intersections
            if (intensity > 0.4) {
              ctx.beginPath();
              ctx.arc(wx, wy, 0.8, 0, Math.PI * 2);
              ctx.fillStyle = `rgba(232,200,135,${intensity * 0.7})`;
              ctx.fill();
            }
          }
        }
      }

      // ── gravitational mass glow at cursor ─────────────────────────────────
      if (active) {
        // wide soft halo
        const halo = ctx.createRadialGradient(mx, my, 0, mx, my, SIGMA * 0.85);
        halo.addColorStop(0,   "rgba(200,169,110,0.07)");
        halo.addColorStop(0.5, "rgba(200,169,110,0.025)");
        halo.addColorStop(1,   "rgba(200,169,110,0)");
        ctx.fillStyle = halo;
        ctx.beginPath();
        ctx.arc(mx, my, SIGMA * 0.85, 0, Math.PI * 2);
        ctx.fill();

        // tight bright core (the "mass")
        const core = ctx.createRadialGradient(mx, my, 0, mx, my, 22);
        core.addColorStop(0, "rgba(240,210,150,0.22)");
        core.addColorStop(1, "rgba(200,169,110,0)");
        ctx.fillStyle = core;
        ctx.beginPath();
        ctx.arc(mx, my, 22, 0, Math.PI * 2);
        ctx.fill();
      }

      raf = requestAnimationFrame(draw);
    };

    draw();

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("resize", resize);
      window.removeEventListener("pointermove", onPointerMove);
      document.documentElement.removeEventListener("pointerleave", onPointerLeave);
      window.removeEventListener("touchstart", onTouch);
      window.removeEventListener("touchmove", onTouch);
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      aria-hidden="true"
      style={{
        position: "fixed",
        inset: 0,
        width: "100%",
        height: "100%",
        pointerEvents: "none",
        zIndex: 0,
      }}
    />
  );
}
