import { FC, memo, useState, useEffect, useRef, useCallback } from 'react';
import { useInView } from 'react-intersection-observer';

import { GifResult } from '@giphy/js-fetch-api';

import { IconGif } from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import { alpha, useTheme } from '@material-hu/mui/styles';

type ControlledGifProps = {
  gif: GifResult;
  duration: number;
  width: number;
  height?: number;
};

const ControlledGif: FC<ControlledGifProps> = ({
  gif,
  duration,
  width,
  height,
}) => {
  const theme = useTheme();
  const [isPlaying, setIsPlaying] = useState(false);
  const [showPlayButton, setShowPlayButton] = useState(false);
  const timerRef = useRef<NodeJS.Timeout | null>(null);

  const { ref: setGifRef, inView } = useInView({
    threshold: 0.5,
  });
  const imgRef = useRef<HTMLImageElement | null>(null);

  const setRef = useCallback(
    (node: HTMLImageElement | null) => {
      imgRef.current = node;
      setGifRef(node);
    },
    [setGifRef],
  );

  // This is used to play the gif when it is in view
  useEffect(() => {
    if (inView && gif?.data) {
      setIsPlaying(true);
      setShowPlayButton(false);
    } else {
      setIsPlaying(false);
      setShowPlayButton(false);
      if (timerRef.current) {
        clearTimeout(timerRef.current);
        timerRef.current = null;
      }
    }
  }, [inView, gif?.data]);

  // This is used to auto-pause the gif after 30 seconds
  useEffect(() => {
    if (isPlaying && inView && gif?.data) {
      timerRef.current = setTimeout(() => {
        setIsPlaying(false);
        setShowPlayButton(true);
      }, duration);
    }

    return () => {
      if (timerRef.current) {
        clearTimeout(timerRef.current);
      }
    };
  }, [isPlaying, inView, gif?.data]);

  const handlePlayClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    setIsPlaying(true);
    setShowPlayButton(false);
  };

  const handleGifClick = (e: React.MouseEvent) => {
    e.stopPropagation();

    if (isPlaying) {
      setIsPlaying(false);
      setShowPlayButton(true);
      if (timerRef.current) {
        clearTimeout(timerRef.current);
        timerRef.current = null;
      }
    } else {
      setIsPlaying(true);
      setShowPlayButton(false);
    }
  };

  const getImageUrl = () => {
    if (isPlaying && inView) {
      return gif.data.images.original?.url || '';
    } else {
      return gif.data.images.original_still?.url || '';
    }
  };

  return (
    <Stack
      sx={{
        position: 'relative',
        display: 'inline-block',
        width,
        height,
      }}
    >
      <img
        ref={setRef}
        src={getImageUrl()}
        width={width}
        height={height}
        onClick={handleGifClick}
        alt="GIF"
        style={{
          width: `${width}px`,
          height: height ? `${height}px` : 'auto',
          borderRadius: '8px',
          display: 'block',
          cursor: 'pointer',
          objectFit: 'contain',
        }}
      />

      {duration > 0 && showPlayButton && (
        <IconButton
          sx={{
            position: 'absolute',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            zIndex: 2,
            background: alpha(theme.palette.new.text.neutral.default, 0.6),
          }}
          onClick={handlePlayClick}
        >
          <IconGif
            size={24}
            color="white"
          />
        </IconButton>
      )}
    </Stack>
  );
};

export default memo(ControlledGif);
