import React, { CSSProperties, FC, forwardRef, Ref, useState } from 'react';

const ImageMagnifier: FC<{
  src: string;
  magnifierHeight?: number;
  magnifierWidth?: number;
  style?: CSSProperties;
  zoomLevel?: number;
  className?: string;
  ref?: Ref<HTMLImageElement>;
}> = forwardRef(
  (
    {
      src,
      magnifierHeight = 600,
      magnifierWidth = 600,
      style,
      zoomLevel = 1.5,
      className,
    },
    ref
  ) => {
    const [[x, y], setXY] = useState([0, 0]);
    const [[imgWidth, imgHeight], setSize] = useState([0, 0]);
    const [showMagnifier, setShowMagnifier] = useState(false);

    return (
      <>
        <img
          ref={ref}
          className={className}
          src={src}
          style={style}
          onMouseDown={(e) => {
            e.preventDefault();
            const elem = e.currentTarget;
            const { width, height } = elem.getBoundingClientRect();
            setSize([width, height]);
            setShowMagnifier(true);
          }}
          onMouseMove={(e) => {
            const elem = e.currentTarget;
            const { top, left } = elem.getBoundingClientRect();
            const x = e.pageX - left - window.pageXOffset;
            const y = e.pageY - top - window.pageYOffset;
            setXY([x, y]);
          }}
          onMouseUp={() => {
            setShowMagnifier(false);
          }}
          alt={'img'}
        />

        <div
          style={{
            display: showMagnifier ? '' : 'none',
            position: 'absolute',
            pointerEvents: 'none',
            width: `${magnifierWidth}px`,
            height: `${magnifierHeight}px`,
            left: '50%',
            top: '50%',
            transform: 'translate(-50%,-50%)',
            opacity: '1',
            border: '1px solid lightgray',
            backgroundColor: 'white',
            backgroundImage: `url('${src}')`,
            backgroundRepeat: 'no-repeat',
            backgroundSize: `${imgWidth * zoomLevel}px ${
              imgHeight * zoomLevel
            }px`,
            backgroundPositionX: `${-x * zoomLevel + magnifierWidth / 2}px`,
            backgroundPositionY: `${-y * zoomLevel + magnifierHeight / 2}px`,
            zIndex: 2000,
          }}
        />
      </>
    );
  }
);

export default ImageMagnifier;
