"use client";

import initCanvas from "@/utils/init-canvas";
import { animate } from "motion";
import { useEffect, useRef } from "react";

export default function EndpointsSearch({
  alwaysHeat,
  size = 20,
}: {
  alwaysHeat?: boolean;
  size?: number;
}) {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const canvas = canvasRef.current;

    if (!canvas) return;

    const ctx = initCanvas(canvas);

    let isRunning = false;
    let isActive = false;

    let diff = 0;
    const defaultRowAlphas = [
      0, 0.2, 0.4, 0, 0.4, 1, 0.4, 0.2, 0.2, 0.4, 1, 0.4, 0, 0.4, 0.2, 0,
    ];

    const differs = Array.from({ length: 16 }, () => 0.2 + Math.random() * 0.2);

    differs[5] = 0.6;
    differs[6] = 0.6;
    differs[9] = 0.6;
    differs[10] = 0.6;

    const scaler = size / 20;

    const render = () => {
      ctx.fillStyle = "#FF4C00";
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      for (let i = 0; i < 16; i++) {
        if ([0, 3, 12, 15].includes(i)) continue;

        const maxAlpha = [5, 6, 9, 10].includes(i) ? 1 : 0.4;

        const alpha = defaultRowAlphas[i] + diff * differs[i];
        ctx.globalAlpha = Math.min(
          Math.min(alpha, maxAlpha) - Math.max(alpha - maxAlpha, 0),
          1,
        );

        ctx.fillRect(
          (3 + (i % 4) * 4) * scaler,
          (3 + Math.floor(i / 4) * 4) * scaler,
          2 * scaler,
          2 * scaler,
        );
      }

      if (isRunning) {
        requestAnimationFrame(render);
      }
    };

    const timeouts: number[] = [];

    let runCount = 0;

    const duration = 300;

    const cycle = () => {
      isRunning = true;

      animate(diff, 1, {
        duration: duration / 1000,
        onUpdate: (value) => {
          diff = value < 0.5 ? value * 2 : 1 - (value - 0.5) * 2;
        },
      });

      timeouts.forEach((timeout) => {
        window.clearTimeout(timeout);
      });

      timeouts.push(
        window.setTimeout(
          () => {
            isRunning = false;
          },
          Math.max(duration, 300),
        ),
      );

      runCount += 1;

      if (runCount === 3 || !isActive) return;

      timeouts.push(
        window.setTimeout(() => {
          cycle();
        }, duration),
      );
    };

    const activate = () => {
      if (isActive) return;

      isActive = true;

      runCount = 0;
      cycle();
      render();
    };

    const deactivate = () => {
      if (!isActive) return;

      isActive = false;
    };

    render();
    canvas.addEventListener("resize", render);

    const group = canvasRef.current!.closest(".group");

    if (group) {
      group.addEventListener("mouseenter", activate);
      group.addEventListener("mouseleave", deactivate);

      return () => {
        group.removeEventListener("mouseenter", activate);
        group.removeEventListener("mouseleave", deactivate);
      };
    }
  }, [size]);

  return <canvas ref={canvasRef} style={{ width: size, height: size }} />;
}
