"use client";

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

const ENGINE_VERSION = "2.0.4";

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 = () => {
      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;
      }
      return 0;
    };

    const isMobile = checkIsMobile();
    // Берем плотность пикселей экрана, ограничиваем до 2.0 для баланса резкости и FPS
    const pixelScale = Math.min(window.devicePixelRatio || 1, 2.0);

    // ЛОГИЧЕСКИЙ размер (в CSS пикселях) - для физики Rust
    const logicalWidth = container.clientWidth;
    const logicalHeight = container.clientHeight;

    dimensionsRef.current = { width: logicalWidth, height: logicalHeight };

    try {
      // ФИЗИЧЕСКИЙ размер Canvas (для резкости)
      canvas.width = logicalWidth * pixelScale;
      canvas.height = logicalHeight * pixelScale;

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

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

      worker.postMessage(
        {
          type: "INIT",
          payload: {
            canvas: offscreen,
            logicalWidth,
            logicalHeight,
            pixelScale,
            eyeY: getEyeY(), // Без scale, так как движок теперь работает в логических координатах
            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 pScale = Math.min(window.devicePixelRatio || 1, 2.0);
          const lw = container.clientWidth;
          const lh = container.clientHeight;
          dimensionsRef.current = { width: lw, height: lh };

          workerRef.current.postMessage({
            type: "RESIZE",
            payload: {
              logicalWidth: lw,
              logicalHeight: lh,
              pixelScale: pScale,
              eyeY: getEyeY(),
              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 || !workerRef.current) return;

    const handleOrientation = (e: DeviceOrientationEvent) => {
      let gamma = e.gamma || 0;
      if (gamma > 45) gamma = 45;
      if (gamma < -45) gamma = -45;
      const tiltX = gamma / 45.0;
      workerRef.current?.postMessage({
        type: "TILT",
        payload: { x: tiltX, y: 0 },
      });
    };

    if (
      typeof (DeviceOrientationEvent as any).requestPermission === "function"
    ) {
      // iOS permission logic omitted for brevity
    } else {
      window.addEventListener("deviceorientation", handleOrientation);
    }

    const handleEvents = (e: any) => {
      const isDown = e.type === "pointerdown" || e.type === "touchstart";
      const isMove = e.type === "pointermove" || e.type === "touchmove";

      const isInteractive = e.target.closest(
        'button, a, input, [role="button"], [role="switch"]',
      );
      if (isDown && isInteractive) return;

      let clientX = e.touches ? e.touches[0].clientX : e.clientX;
      let clientY = e.touches ? e.touches[0].clientY : e.clientY;

      if (clientX === undefined) return;

      const rect = canvasRef.current!.getBoundingClientRect();
      // Scale теперь всегда 1.0, так как dimensionsRef равен логическому CSS размеру
      const scaleX = dimensionsRef.current.width / rect.width;
      const scaleY = dimensionsRef.current.height / rect.height;
      const px = (clientX - rect.left) * scaleX;
      const py = (clientY - rect.top) * scaleY;

      if (isDown) {
        workerRef.current?.postMessage({
          type: "SHOCKWAVE",
          payload: { x: px, y: py },
        });
      }
      if (isMove) {
        workerRef.current?.postMessage({
          type: "KINETIC_SWIPE",
          payload: { x: px, y: py },
        });
      }
    };

    window.addEventListener("pointerdown", handleEvents, { passive: true });
    window.addEventListener("pointermove", handleEvents, { passive: true });
    window.addEventListener("touchstart", handleEvents, { passive: true });
    window.addEventListener("touchmove", handleEvents, { passive: true });

    return () => {
      window.removeEventListener("deviceorientation", handleOrientation);
      window.removeEventListener("pointerdown", handleEvents);
      window.removeEventListener("pointermove", handleEvents);
      window.removeEventListener("touchstart", handleEvents);
      window.removeEventListener("touchmove", 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>
  );
};
