import { useSelector } from 'react-redux';
import { ThemeOverflow } from '../../redux/reducers/themeReducer/model';
import { RootState } from '../../redux/store';
import { motion, useAnimation } from 'framer-motion';
import { useEffect, useState } from 'react';

interface Props {
  children: (JSX.Element | string)[] | string | JSX.Element;
  animate?: boolean;
  className?: string;
}

const variants = {
  initial: (props: { y: number }) => {
    const y = props?.y || '100%';
    return {
      y: y,
    };
  },
  show: (props: { duration: number }) => {
    const duration = props?.duration || 4.2;
    return {
      y: '0px',
      transition: {
        duration: duration,
        ease: [0.42, 0, 1, 1],
      },
    };
  },
};

interface Custom {
  y?: string;
  duration: number;
}

const ThemeWrapper = (props: Props) => {
  const { overflow, show, imagesContainerHeight, isVisible, isVideoVisible } =
    useSelector((state: RootState) => ({
      ...state.theme,
      isVisible: state.initialLoader.isVisible,
      imagesContainerHeight: state.initialLoader.imagesContainerHeight,
      isVideoVisible: state.initialVideo.isVisible,
    }));
  let mql = process.browser
    ? window.matchMedia('(min-width: 900px)')
    : undefined;
  const { children, className } = props;
  const controls = useAnimation();
  const [mounted, setMounted] = useState(false);
  const [custom, setCustom] = useState<Custom | undefined>();
  const [classNames, setClassNames] = useState(`${className || ''}`);

  useEffect(() => {
    setClassNames(
      `${className || ''} ${overflow === ThemeOverflow.HIDDEN ? 'hidden' : ''}`
    );
  }, [overflow, className]);

  useEffect(() => {
    if (!isVisible) {
      controls.set('show');
      document.body.classList.remove('loading');
    }
    if (show && imagesContainerHeight && mounted) {
      setCustom({
        duration: mql?.matches ? 4.2 : 3.2,
      });
    } else {
      if (!isVisible) {
        controls.set({ y: 'unset' });
        document.body.classList.remove('loading');
      }
    }
  }, [show, controls, imagesContainerHeight, mounted, isVisible, mql?.matches]);

  useEffect(() => {
    if (imagesContainerHeight && mounted && isVisible) {
      document.body.classList.add('loading');
      controls.set({
        y: `${window?.innerHeight + imagesContainerHeight}px`,
      });
    }
  }, [imagesContainerHeight, mounted]);

  useEffect(() => {
    if (custom && mounted) {
      controls.start('show');
    }
  }, [custom, mounted]);

  useEffect(() => {
    if (!isVideoVisible) {
      window.scrollTo(0, 0);
      window.history.scrollRestoration = 'auto';
      setMounted(true);
    }
  }, [isVideoVisible]);

  return (
    <motion.div
      className={classNames}
      initial={'initial'}
      animate={controls}
      custom={custom}
      variants={variants}
      onAnimationComplete={() => {
        window.requestAnimationFrame(() => {
          controls.set({ y: 'unset' });
        });
      }}
      transformTemplate={({ y }) =>
        y === 'unset' || y === '0px' ? 'unset' : `translateY(${y})`
      }
    >
      {children}
    </motion.div>
  );
};

export default ThemeWrapper;
