import { useScroll, useTransform, motion } from 'framer-motion';
import { Image as ImageI } from '../../models/common';
import styles from './Image.module.scss';
import { useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '../../redux/store';
import { isInitialLoaderVisible } from '../../api/storage';
import { useMediaQuery } from 'react-responsive';
import NextImage from 'next/legacy/image';

type Props = {
  image: ImageI;
  alt: string;
  isParralaxImg?: boolean;
  parallaxRange?: number[];
};

const Image = (props: Props): JSX.Element => {
  const isDesktop = useMediaQuery({ query: '(min-width: 560px)' });
  const isSmallScreen = useMediaQuery({ query: '(max-width: 1024px)' });
  const { isVisible } = useSelector((state: RootState) => ({
    ...state.initialLoader,
  }));
  const isLoaderVisible = !isVisible || !isInitialLoaderVisible();
  const {
    image,
    alt,
    isParralaxImg = false,
    parallaxRange = isDesktop ? [-40, 40] : [-30, 30],
  } = props;
  const { scrollY } = useScroll();
  const _ref = useRef<HTMLDivElement | null>(null);
  const [yRange, setYRange] = useState<number[]>([0, 0]);
  const [width, setWidth] = useState<number>(0);
  const y = useTransform(scrollY, yRange, parallaxRange);

  useEffect(() => {
    if (!isParralaxImg) return;
    const handleElementTop = (): void => {
      window.requestAnimationFrame(() => {
        const element = _ref.current;
        const offsetTop =
          element?.offsetTop ||
          element?.parentElement?.parentElement?.offsetTop;
        const rect = element?.getBoundingClientRect();
        const height = rect?.height || 0;
        if (offsetTop)
          setYRange([
            offsetTop - ((process.browser && window.innerHeight) || 0),
            offsetTop + height,
          ]);
        setWidth(rect?.width || 0);
      });
    };

    window.addEventListener('resize', handleElementTop);
    if (_ref && isLoaderVisible) handleElementTop();

    return () => {
      window.removeEventListener('resize', handleElementTop);
    };
  }, [_ref, isLoaderVisible, isParralaxImg]);

  useEffect(() => {
    const resize = () => {
      if (isParralaxImg || !_ref.current) return;
      const element = _ref.current;
      const rect = element?.getBoundingClientRect();
      setWidth(rect?.width || 0);
    };
    resize();
    window.addEventListener('resize', resize);

    return () => {
      window.removeEventListener('resize', resize);
    };
  }, [isParralaxImg, image, _ref.current]);

  let imageSizes = `${image?.width || width}px`;


  //if (isSmallScreen){
    imageSizes = "(max-width:1024px) 50vw, 1280px"
  //}


  return isParralaxImg ? (
    <div ref={_ref} className={styles.parallaxImage}>
      <motion.div
        initial={false}
        style={{
          y: y,
          marginTop: parallaxRange[0] / 2,
          marginBottom: parallaxRange[0] / 2,
          left: parallaxRange[0] / 2,
          width: `calc(100% + ${parallaxRange[1]}px)`,
        }}
      >
        <NextImage
          src={image?.src || ''}
          width={image?.width || 1280}
          height={image?.height || 1280}
          alt={image?.alt || alt || ''}
          layout={image?.layout || 'responsive'}
          quality={image?.quality || 80}
          lazyBoundary={'500px'}
          loading={image.loading || 'eager'}
          sizes={
            image?.layout === 'intrinsic' || image?.layout === 'fixed'
              ? undefined
              : image?.width || width
              ? imageSizes
              : imageSizes
          }
          priority={image?.priority || false}
        />
      </motion.div>
    </div>
  ) : (
    <div ref={_ref} className={styles.image}>
      <NextImage
        src={image?.src || ''}
        alt={image?.alt || alt || ''}
        width={image?.width || 1280}
        height={image?.height || 1280}
        layout={image?.layout || 'responsive'}
        quality={image?.quality || 80}
        lazyBoundary={'500px'}
        loading={image.loading || 'eager'}
        sizes={
          image?.layout === 'intrinsic' || image?.layout === 'fixed'
            ? undefined
            : image?.width || width
            ? imageSizes
            : imageSizes
        }
        priority={image?.priority || false}
      />
    </div>
  );
};

export default Image;
