import { useQuery } from 'react-query';

import { conversationKeys } from '../queries';

const generatePosterFromVideo = (videoUrl: string): Promise<string> => {
  return new Promise((resolve, reject) => {
    const tempVideo = document.createElement('video');
    tempVideo.crossOrigin = 'anonymous';
    tempVideo.muted = true;
    tempVideo.preload = 'metadata';
    tempVideo.style.position = 'absolute';
    tempVideo.style.left = '-9999px';
    tempVideo.style.top = '-9999px';
    tempVideo.style.width = '1px';
    tempVideo.style.height = '1px';

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    if (!ctx) {
      reject();
      return;
    }

    const cleanup = () => {
      tempVideo.removeEventListener('loadeddata', handleLoadedData);
      tempVideo.removeEventListener('seeked', handleSeeked);
      tempVideo.removeEventListener('error', handleError);
      if (tempVideo.parentNode) {
        tempVideo.parentNode.removeChild(tempVideo);
      }
    };

    const handleLoadedData = () => {
      canvas.width = tempVideo.videoWidth;
      canvas.height = tempVideo.videoHeight;
      tempVideo.currentTime = 0.1;
    };

    const handleSeeked = () => {
      try {
        ctx.drawImage(tempVideo, 0, 0, canvas.width, canvas.height);
        const dataURL = canvas.toDataURL('image/jpeg', 0.8);
        cleanup();
        resolve(dataURL);
      } catch (error) {
        cleanup();
        reject(error);
      }
    };

    const handleError = () => {
      cleanup();
      reject();
    };

    tempVideo.addEventListener('loadeddata', handleLoadedData);
    tempVideo.addEventListener('seeked', handleSeeked);
    tempVideo.addEventListener('error', handleError);

    document.body.appendChild(tempVideo);
    tempVideo.src = videoUrl;
  });
};

const useGeneratePosterVideos = ({
  correctVideoUrl,
  thumbnailUrl,
}: {
  correctVideoUrl: string;
  thumbnailUrl?: string;
}) => {
  const shouldGeneratePoster = Boolean(correctVideoUrl) && !thumbnailUrl;

  const {
    data: generatedPoster,
    isLoading: isGeneratingPoster,
    refetch,
    isError,
    isSuccess,
  } = useQuery(
    conversationKeys.poster(correctVideoUrl),
    () => generatePosterFromVideo(correctVideoUrl),
    {
      enabled: shouldGeneratePoster,
      staleTime: Infinity,
    },
  );

  return {
    generatedPoster: generatedPoster ?? null,
    isGeneratingPoster,
    isError,
    isSuccess,
    refetch,
  };
};

export default useGeneratePosterVideos;
