import { useRef, useEffect } from 'react';

const HEX_COUNT = 60;
const TAU = Math.PI * 2;

interface Hex {
  x: number;
  y: number;
  baseY: number;
  size: number;
  opacity: number;
  speed: number;
  phase: number;
}

function initHexes(w: number, h: number): Hex[] {
  const hexes: Hex[] = [];
  for (let i = 0; i < HEX_COUNT; i++) {
    const y = Math.random() * h;
    hexes.push({
      x: Math.random() * w,
      y,
      baseY: y,
      size: 8 + Math.random() * 20,
      opacity: 0.06 + Math.random() * 0.12,
      speed: 6 + Math.random() * 14,
      phase: Math.random() * TAU,
    });
  }
  return hexes;
}

function drawHex(ctx: CanvasRenderingContext2D, cx: number, cy: number, r: number) {
  ctx.beginPath();
  for (let i = 0; i < 6; i++) {
    const angle = (TAU / 6) * i - Math.PI / 6;
    const px = cx + r * Math.cos(angle);
    const py = cy + r * Math.sin(angle);
    if (i === 0) ctx.moveTo(px, py);
    else ctx.lineTo(px, py);
  }
  ctx.closePath();
}

export default function HexCanvas({
  scrollProgress,
  isDark = false,
}: {
  scrollProgress: number;
  isDark?: boolean;
}) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const hexesRef = useRef<Hex[]>([]);
  const animRef = useRef(0);
  const scrollRef = useRef(scrollProgress);
  scrollRef.current = scrollProgress;
  const isDarkRef = useRef(isDark);
  isDarkRef.current = isDark;

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

    let w = 0;
    let h = 0;

    function resize() {
      const dpr = window.devicePixelRatio || 1;
      const rect = canvas!.parentElement!.getBoundingClientRect();
      w = rect.width;
      h = rect.height;
      canvas!.width = w * dpr;
      canvas!.height = h * dpr;
      canvas!.style.width = `${w}px`;
      canvas!.style.height = `${h}px`;
      ctx!.setTransform(dpr, 0, 0, dpr, 0, 0);
      hexesRef.current = initHexes(w, h);
    }

    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(canvas.parentElement!);

    let prev = performance.now();

    function frame(now: number) {
      const dt = (now - prev) / 1000;
      prev = now;
      const scroll = scrollRef.current;
      ctx!.clearRect(0, 0, w, h);

      const globalAlpha = Math.max(0, 1 - scroll * 2);

      for (const hex of hexesRef.current) {
        hex.x = (hex.x + hex.speed * dt) % (w + hex.size * 2);
        const bob = Math.sin(now / 1000 + hex.phase) * 8;
        const parallax = scroll * h * 0.3 * (hex.speed / 20);
        hex.y = hex.baseY + bob - parallax;

        if (hex.y < -hex.size * 2) hex.y += h + hex.size * 4;
        if (hex.y > h + hex.size * 2) hex.y -= h + hex.size * 4;

        const dark = isDarkRef.current;
        ctx!.globalAlpha = hex.opacity * globalAlpha * (dark ? 0.6 : 1);
        ctx!.fillStyle = dark ? '#058172' : '#00a28c';
        drawHex(ctx!, hex.x, hex.y, hex.size);
        ctx!.fill();

        ctx!.globalAlpha = hex.opacity * 0.5 * globalAlpha * (dark ? 0.6 : 1);
        ctx!.strokeStyle = dark ? '#0a665b' : '#05c9aa';
        ctx!.lineWidth = 1;
        drawHex(ctx!, hex.x, hex.y, hex.size);
        ctx!.stroke();
      }

      animRef.current = requestAnimationFrame(frame);
    }

    animRef.current = requestAnimationFrame(frame);
    return () => {
      cancelAnimationFrame(animRef.current);
      ro.disconnect();
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      className="absolute inset-0 pointer-events-none"
      style={{ zIndex: 0 }}
    />
  );
}
