"use client";

import React, { useRef, useEffect, useState } from "react";
import { useTheme } from "next-themes";

interface NetrunnerMatrixProps {
  isSecure?: boolean;
}

export const NetrunnerMatrix: React.FC<NetrunnerMatrixProps> = ({
  isSecure = false,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const workerRef = useRef<Worker | null>(null);
  const dimensionsRef = useRef({ width: 0, height: 0 });
  const [isLoaded, setIsLoaded] = useState(false);
  const hasTransferred = useRef(false);

  const { resolvedTheme, theme } = useTheme();
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
    return () => setMounted(false);
  }, []);

  const isDarkMode = mounted
    ? resolvedTheme === "dark" || theme === "dark"
    : true;

  const checkIsMobile = () => {
    if (typeof window === "undefined") return false;
    return window.innerWidth <= 768 || "ontouchstart" in window;
  };

  useEffect(() => {
    if (
      !mounted ||
      typeof window === "undefined" ||
      !("OffscreenCanvas" in window)
    )
      return;

    const canvas = canvasRef.current;
    const container = containerRef.current;

    if (!canvas || !container || hasTransferred.current) return;

    
    const getEyeY = (scale: number) => {
      const anchor = document.getElementById("eye-anchor");
      const canvas = canvasRef.current;
      if (anchor && canvas) {
        const ar = anchor.getBoundingClientRect();
        const cr = canvas.getBoundingClientRect();
        return (ar.top - cr.top + ar.height / 2) * scale;
      }
      return 0;
    };

    const isMobile = checkIsMobile();
    const pixelScale = isMobile
      ? 1.0
      : Math.min(window.devicePixelRatio || 1, 1.5);
    const initialWidth = container.clientWidth * pixelScale;
    const initialHeight = container.clientHeight * pixelScale;

    dimensionsRef.current = { width: initialWidth, height: initialHeight };

    try {
      canvas.width = initialWidth;
      canvas.height = initialHeight;

      const worker = new Worker("/wasm-matrix/matrix_worker.js", {
        type: "module",
      });
      workerRef.current = worker;

      const offscreen = canvas.transferControlToOffscreen();
      hasTransferred.current = true;

      worker.postMessage(
        {
          type: "INIT",
          payload: {
            canvas: offscreen,
            width: initialWidth,
            height: initialHeight,
            eyeY: getEyeY(pixelScale),
            isMobile,
            isVpnOn: isSecure,
            isDarkMode,
            fontSize: isMobile ? 10 : 16,
          },
        },
        [offscreen],
      );

      setIsLoaded(true);

      let resizeTimeout: ReturnType<typeof setTimeout>;
      const handleResize = () => {
        clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(() => {
          if (!container || !workerRef.current) return;
          const isMob = checkIsMobile();
          const scale = isMob ? 1.0 : Math.min(window.devicePixelRatio || 1, 1.5);
          const w = container.clientWidth * scale;
          const h = container.clientHeight * scale;
          dimensionsRef.current = { width: w, height: h };
          workerRef.current.postMessage({
            type: "RESIZE",
            payload: {
              width: w,
              height: h,
              eyeY: getEyeY(scale),
              isMobile: isMob,
              fontSize: isMob ? 10 : 16,
            },
          });
        }, 150);
      };

      window.addEventListener("resize", handleResize);

      return () => {
        window.removeEventListener("resize", handleResize);
        clearTimeout(resizeTimeout);
        if (workerRef.current) {
          workerRef.current.terminate();
          workerRef.current = null;
        }
        hasTransferred.current = false;
      };
    } catch (e) {
      console.error("Matrix Worker Bridge Failed:", e);
    }
  }, [mounted]);

  useEffect(() => {
    if (workerRef.current && mounted) {
      workerRef.current.postMessage({
        type: "THEME",
        payload: { isVpnOn: isSecure, isDarkMode },
      });
    }
  }, [isSecure, isDarkMode, mounted]);

  useEffect(() => {
    if (!mounted) return;

    const handleEvents = (e: any) => {
      if (!workerRef.current || !canvasRef.current) return;

      const isInteractive = e.target.closest(
        'button, a, input, [role="button"], [role="switch"], .data-\\[state\\]',
      );

      const isDown = e.type === "pointerdown" || e.type === "touchstart";
      const isUp =
        e.type === "pointerup" ||
        e.type === "touchend" ||
        e.type === "pointercancel";

      if (isInteractive && isDown) return;

      const type = isDown ? "DRAW_START" : isUp ? "DRAW_END" : "MOUSE_MOVE";

      let clientX: number | null = null;
      let clientY: number | null = null;

      if (e.touches && e.touches.length > 0) {
        clientX = e.touches[0].clientX;
        clientY = e.touches[0].clientY;
      } else if (e.clientX !== undefined) {
        clientX = e.clientX;
        clientY = e.clientY;
      }

      if (clientX === null || clientY === null) {
        if (isUp) workerRef.current.postMessage({ type });
        return;
      }

      const rect = canvasRef.current.getBoundingClientRect();
      const scaleX = dimensionsRef.current.width / rect.width;
      const scaleY = dimensionsRef.current.height / rect.height;

      workerRef.current.postMessage({
        type,
        payload: {
          x: (clientX - rect.left) * scaleX,
          y: (clientY - rect.top) * scaleY,
        },
      });
    };

    const options = { passive: true };
    
    if (window.PointerEvent) {
      window.addEventListener("pointerdown", handleEvents, options as any);
      window.addEventListener("pointermove", handleEvents, options as any);
      window.addEventListener("pointerup", handleEvents, options as any);
      window.addEventListener("pointercancel", handleEvents, options as any);
    } else {
      window.addEventListener("touchstart", handleEvents, options);
      window.addEventListener("touchmove", handleEvents, options);
      window.addEventListener("touchend", handleEvents, options);
    }

    return () => {
      if (window.PointerEvent) {
        window.removeEventListener("pointerdown", handleEvents);
        window.removeEventListener("pointermove", handleEvents);
        window.removeEventListener("pointerup", handleEvents);
        window.removeEventListener("pointercancel", handleEvents);
      } else {
        window.removeEventListener("touchstart", handleEvents);
        window.removeEventListener("touchmove", handleEvents);
        window.removeEventListener("touchend", handleEvents);
      }
    };
  }, [mounted]);

  return (
    <div
      ref={containerRef}
      className="absolute inset-0 overflow-hidden z-0 bg-background"
    >
      <canvas
        key="matrix-canvas"
        ref={canvasRef}
        className={`w-full h-full block transition-opacity duration-1000 ${isLoaded ? "opacity-100" : "opacity-0"}`}
      />
      <div
        className="absolute inset-0 pointer-events-none opacity-[0.15] dark:opacity-[0.25] hidden md:block"
        style={{
          background: `linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06))`,
          backgroundSize: "100% 4px, 3px 100%",
        }}
      />
    </div>
  );
};
