import { useCallback, useContext, useEffect, useState } from 'react';

import { PublishSongModalScreenType } from '@/components/modal/constants/ModalTypes';
import ContestClipContext from '@/hooks/useContestClip';
import type {
  GenerationCarouselState,
  ScreenNavigationState,
} from '@/hooks/useSongModal';
import { Clip } from '@/state/clipStore';
import { getClipTitle } from '@/utils/clip';

// TODO: refactor this once VideoUploader is removed?
function useEditClipMetadata(
  clip?: Clip,
  navigateTo?: (
    screen: PublishSongModalScreenType,
    state?: ScreenNavigationState
  ) => void
) {
  const [editedTitle, setEditedTitle] = useState(
    !!clip ? getClipTitle(clip) : ''
  );
  const [editedImagePrompt, setEditedImagePrompt] = useState('');
  const [isGeneratingCover, setIsGeneratingCover] = useState(false);
  const [isViewingGenerateHistory, setIsViewingGenerateHistory] =
    useState(false);
  const [isViewingGenerationFavorites, setIsViewingGenerationFavorites] =
    useState(false);

  // Create wrapper function for opening generation carousel with state
  const navigateToGenerationCarousel = useCallback(
    (state: GenerationCarouselState) => {
      if (navigateTo) {
        navigateTo('generationCarousel', {
          generationCarousel: state,
        });
      }
    },
    [navigateTo]
  );
  const [s3Id, setS3Id] = useState<string | null>(null);
  const [currentImage, setCurrentImage] = useState<string | null | undefined>(
    clip?.image_url ?? undefined
  );
  const [isLoading, setIsLoading] = useState(false);
  const [isAddingImage, setIsAddingImage] = useState(false);
  const [isGenerating, setIsGenerating] = useState(false);
  const [addedImages, setAddedImages] = useState<(string | null)[]>([]);
  const [addingImageDataURL, setAddingImageDataURL] = useState<string | null>(
    null
  );
  const [addingImageChanged, setAddingImageChanged] = useState(false);
  const [continuedClips, setContinuedClips] = useState<Clip[]>([]);
  const [initialImageURL, setInitialImageURL] = useState<string | null>(null);
  const [currentActiveClip, setCurrentActiveClip] = useState(clip);
  const [currentLyrics, setCurrentLyrics] = useState(
    clip?.metadata?.prompt || ''
  );
  const [currentCaption, setCurrentCaption] = useState(clip?.caption || '');
  const [currentCaptionMentions, setCurrentCaptionMentions] = useState(
    clip?.caption_mentions?.user_mentions || []
  );
  const [isAddingMedia, setIsAddingMedia] = useState(false);
  const [selectedVideo, setSelectedVideo] = useState<File | null | undefined>(
    undefined
  );
  const [displayTags, setDisplayTags] = useState(clip?.display_tags || '');

  const { isContestSubmission } = useContext(ContestClipContext);
  const [submitToContest, setSubmitToContest] = useState(
    isContestSubmission({ clip: clip || undefined })
  );

  // TODO: remove this to properly clear display tags when canceled
  useEffect(() => {
    setDisplayTags(clip?.display_tags || '');
  }, [clip?.display_tags]);

  return {
    editedTitle,
    setEditedTitle,
    s3Id,
    setS3Id,
    editedImagePrompt,
    setEditedImagePrompt,
    currentImage,
    setCurrentImage,
    isLoading,
    setIsLoading,
    isGenerating,
    setIsGenerating,
    addedImages,
    setAddedImages,
    isAddingImage,
    setIsAddingImage,
    addingImageDataURL,
    setAddingImageDataURL,
    addingImageChanged,
    setAddingImageChanged,
    continuedClips,
    setContinuedClips,
    initialImageURL,
    setInitialImageURL,
    currentActiveClip,
    setCurrentActiveClip,
    currentLyrics,
    setCurrentLyrics,
    currentCaption,
    setCurrentCaption,
    currentCaptionMentions,
    setCurrentCaptionMentions,
    isAddingMedia,
    setIsAddingMedia,
    selectedVideo,
    setSelectedVideo,
    displayTags,
    setDisplayTags,
    submitToContest,
    setSubmitToContest,
    isGeneratingCover,
    setIsGeneratingCover,
    navigateToGenerationCarousel,
    isViewingGenerateHistory,
    setIsViewingGenerateHistory,
    isViewingGenerationFavorites,
    setIsViewingGenerationFavorites,
  };
}

export default useEditClipMetadata;
