"use client";

import React, { useRef, useEffect } from "react";

interface BlinkingSquaresProps {
  squareSize?: number;
  gap?: number;
  color?: string;
  maxOpacity?: number;
  minOpacity?: number;
  blinkProbability?: number;
  className?: string;
  interactive?: boolean;
}

export function BlinkingSquares({
  squareSize = 16,
  gap = 6,
  color = "#024d37",
  maxOpacity = 0.45,
  minOpacity = 0.04,
  blinkProbability = 0.015,
  className = "",
  interactive = true,
}: BlinkingSquaresProps) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);

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

    let animationFrameId: number;
    let width = 0;
    let height = 0;

    interface Square {
      x: number;
      y: number;
      baseOpacity: number;
      targetOpacity: number;
      currentOpacity: number;
      speed: number;
    }

    let squares: Square[] = [];
    let mousePos = { x: -1000, y: -1000 };

    const initSquares = () => {
      if (!containerRef.current || !canvas) return;
      const rect = containerRef.current.getBoundingClientRect();
      width = rect.width;
      height = rect.height;

      const dpr = window.devicePixelRatio || 1;
      canvas.width = width * dpr;
      canvas.height = height * dpr;
      ctx.scale(dpr, dpr);

      const step = squareSize + gap;
      const cols = Math.ceil(width / step) + 1;
      const rows = Math.ceil(height / step) + 1;

      squares = [];
      for (let r = 0; r < rows; r++) {
        for (let c = 0; c < cols; c++) {
          const initOp = Math.random() * (maxOpacity - minOpacity) * 0.4 + minOpacity;
          squares.push({
            x: c * step,
            y: r * step,
            baseOpacity: initOp,
            targetOpacity: initOp,
            currentOpacity: initOp,
            speed: 0.005 + Math.random() * 0.012,
          });
        }
      }
    };

    initSquares();

    const handleResize = () => {
      initSquares();
    };

    const handleMouseMove = (e: MouseEvent) => {
      if (!containerRef.current) return;
      const rect = containerRef.current.getBoundingClientRect();
      mousePos = {
        x: e.clientX - rect.left,
        y: e.clientY - rect.top,
      };
    };

    const handleMouseLeave = () => {
      mousePos = { x: -1000, y: -1000 };
    };

    window.addEventListener("resize", handleResize);
    if (interactive && containerRef.current) {
      containerRef.current.addEventListener("mousemove", handleMouseMove);
      containerRef.current.addEventListener("mouseleave", handleMouseLeave);
    }

    // Convert hex or rgb color to rgb numbers for rgba formatting
    const parseColor = (col: string) => {
      if (col.startsWith("#")) {
        const hex = col.replace("#", "");
        const num = parseInt(hex.length === 3 ? hex.split("").map((c) => c + c).join("") : hex, 16);
        return {
          r: (num >> 16) & 255,
          g: (num >> 8) & 255,
          b: num & 255,
        };
      }
      return { r: 2, g: 77, b: 55 };
    };

    const { r, g, b } = parseColor(color);

    const render = () => {
      ctx.clearRect(0, 0, width, height);

      for (let i = 0; i < squares.length; i++) {
        const sq = squares[i];

        // Randomly trigger twinkle/blink
        if (Math.random() < blinkProbability && sq.currentOpacity === sq.targetOpacity) {
          sq.targetOpacity = minOpacity + Math.random() * (maxOpacity - minOpacity);
          sq.speed = 0.008 + Math.random() * 0.02;
        }

        // Smoothly interpolate opacity towards target
        if (sq.currentOpacity < sq.targetOpacity) {
          sq.currentOpacity = Math.min(sq.targetOpacity, sq.currentOpacity + sq.speed);
        } else if (sq.currentOpacity > sq.targetOpacity) {
          sq.currentOpacity = Math.max(sq.targetOpacity, sq.currentOpacity - sq.speed);
        }

        let renderOpacity = sq.currentOpacity;

        // Proximity glow on mouse hover
        if (interactive && mousePos.x >= 0 && mousePos.y >= 0) {
          const dx = mousePos.x - (sq.x + squareSize / 2);
          const dy = mousePos.y - (sq.y + squareSize / 2);
          const dist = Math.sqrt(dx * dx + dy * dy);
          const hoverRadius = 140;

          if (dist < hoverRadius) {
            const proximity = 1 - dist / hoverRadius;
            renderOpacity = Math.min(0.85, renderOpacity + proximity * 0.55);
          }
        }

        ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${renderOpacity})`;
        // Draw rounded rectangle for soft modern aesthetic
        const rad = 2.5;
        ctx.beginPath();
        ctx.roundRect(sq.x, sq.y, squareSize, squareSize, rad);
        ctx.fill();
      }

      animationFrameId = requestAnimationFrame(render);
    };

    render();

    return () => {
      cancelAnimationFrame(animationFrameId);
      window.removeEventListener("resize", handleResize);
      if (interactive && containerRef.current) {
        containerRef.current.removeEventListener("mousemove", handleMouseMove);
        containerRef.current.removeEventListener("mouseleave", handleMouseLeave);
      }
    };
  }, [squareSize, gap, color, maxOpacity, minOpacity, blinkProbability, interactive]);

  return (
    <div
      ref={containerRef}
      className={`pointer-events-none absolute inset-0 h-full w-full overflow-hidden ${className}`}
      aria-hidden="true"
    >
      <canvas ref={canvasRef} className="h-full w-full" />
    </div>
  );
}
