// components/ImageMagnifier.tsx
"use client";

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

interface ImageMagnifierProps {
  src: string;
  alt: string;
  className?: string;
  magnifierSize?: number;
  zoomLevel?: number;
}

export default function ImageMagnifier({
  src,
  alt,
  className = "",
  magnifierSize = 150,
  zoomLevel = 2.5,
}: ImageMagnifierProps) {
  const [showMagnifier, setShowMagnifier] = useState(false);
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [bgPosition, setBgPosition] = useState({ x: 0, y: 0 });
  const [imgDimensions, setImgDimensions] = useState({ width: 0, height: 0 });
  const [isImageLoaded, setIsImageLoaded] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
  const imgRef = useRef<HTMLImageElement>(null);

  // Update dimensions when image loads or src changes
  const updateDimensions = useCallback(() => {
    if (imgRef.current) {
      const width = imgRef.current.offsetWidth || imgRef.current.naturalWidth;
      const height =
        imgRef.current.offsetHeight || imgRef.current.naturalHeight;

      if (width > 0 && height > 0) {
        setImgDimensions({ width, height });
        setIsImageLoaded(true);
      }
    }
  }, []);

  useEffect(() => {
    // Check if image is already loaded
    if (imgRef.current) {
      if (imgRef.current.complete && imgRef.current.naturalWidth > 0) {
        updateDimensions();
      } else {
        // Wait for image to load
        const handleLoad = () => {
          updateDimensions();
        };
        imgRef.current.addEventListener("load", handleLoad);

        return () => {
          imgRef.current?.removeEventListener("load", handleLoad);
        };
      }
    }
  }, [src, updateDimensions]);

  // Handle resize
  useEffect(() => {
    const handleResize = () => {
      updateDimensions();
    };

    window.addEventListener("resize", handleResize);

    // Use ResizeObserver for more accurate container size changes
    if (containerRef.current) {
      const resizeObserver = new ResizeObserver(() => {
        updateDimensions();
      });
      resizeObserver.observe(containerRef.current);

      return () => {
        resizeObserver.disconnect();
        window.removeEventListener("resize", handleResize);
      };
    }

    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, [updateDimensions]);

  const handleMouseEnter = useCallback(() => {
    if (isImageLoaded) {
      setShowMagnifier(true);
    }
  }, [isImageLoaded]);

  const handleMouseLeave = useCallback(() => {
    setShowMagnifier(false);
  }, []);

  const handleMouseMove = useCallback(
    (e: React.MouseEvent<HTMLDivElement>) => {
      if (!imgRef.current || !isImageLoaded) return;

      const rect = imgRef.current.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;

      // Check if mouse is within image bounds
      if (x < 0 || y < 0 || x > rect.width || y > rect.height) {
        setShowMagnifier(false);
        return;
      }

      // Calculate magnifier position
      const halfSize = magnifierSize / 2;
      const magnifierX = Math.max(
        0,
        Math.min(x - halfSize, rect.width - magnifierSize),
      );
      const magnifierY = Math.max(
        0,
        Math.min(y - halfSize, rect.height - magnifierSize),
      );

      // Calculate background position percentage
      const bgX = (x / rect.width) * 100;
      const bgY = (y / rect.height) * 100;

      setPosition({ x: magnifierX, y: magnifierY });
      setBgPosition({ x: bgX, y: bgY });
    },
    [magnifierSize, isImageLoaded],
  );

  // Prevent default drag behavior
  const handleDragStart = useCallback((e: React.DragEvent) => {
    e.preventDefault();
  }, []);

  return (
    <div
      ref={containerRef}
      className={`relative overflow-hidden ${className}`}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      onMouseMove={handleMouseMove}
      onDragStart={handleDragStart}
      style={{
        cursor: isImageLoaded ? "zoom-in" : "default",
        touchAction: "none", // Prevent touch scrolling interference
      }}
    >
      <img
        ref={imgRef}
        src={src}
        alt={alt}
        className="h-auto w-full select-none object-cover"
        draggable={false}
        onLoad={updateDimensions}
        onError={() => {
          // Handle image load error
          console.error(`Failed to load image: ${src}`);
          setIsImageLoaded(false);
        }}
      />

      {showMagnifier && isImageLoaded && imgDimensions.width > 0 && (
        <div
          className="pointer-events-none absolute rounded-full border-2 border-white shadow-lg"
          style={{
            width: `${Math.min(magnifierSize, imgDimensions.width)}px`,
            height: `${Math.min(magnifierSize, imgDimensions.height)}px`,
            left: `${position.x}px`,
            top: `${position.y}px`,
            backgroundImage: `url(${src})`,
            backgroundSize: `${imgDimensions.width * zoomLevel}px ${imgDimensions.height * zoomLevel}px`,
            backgroundPosition: `${bgPosition.x}% ${bgPosition.y}%`,
            backgroundRepeat: "no-repeat",
            zIndex: 50,
            boxShadow:
              "0 0 20px rgba(0,0,0,0.3), 0 0 0 2px rgba(255,255,255,0.8)",
            transition: "none",
          }}
        />
      )}
    </div>
  );
}
