import { AnimatePresence } from 'framer-motion';
import { observer } from 'mobx-react-lite';
import React, { useEffect } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import { ContextType } from '@/logging/contextTypes';

import { useSongPreviewAnalytics } from '../hooks/useSongPreviewAnalytics';
import { SongPreviewCardContainerProps } from '../utils/songPreviewTypes';
import { LoadingPreviewCard } from './LoadingPreviewCard';
import { SongPreviewCard } from './SongPreviewCard';
import { SongPreviewCardSignUpRequired } from './SongPreviewCardSignUpRequired';

// Show signup when user stops playback with buffer of 2 seconds
const SIGNUP_PLAYBACK_THRESHOLD = 28;

export const SongPreviewCardContainer: React.FC<SongPreviewCardContainerProps> =
  observer(
    ({
      clip,
      isLoading: externalIsLoading,
      onSignUp,
      signUpToListen = 'Sign up to listen',
      requireSignUp = false,
    }) => {
      const { playbar, queue: queueStore, clips } = useStores();
      const wasPlayingRef = React.useRef(false);

      const clipId = clip?.id;
      const title = clip?.title || 'Your Song';
      const imageUrl = clip?.image_url ?? undefined;
      const styles = clip?.display_tags || 'pop';
      const audioUrl = clip?.audio_url ?? undefined;

      const isLoading = externalIsLoading ?? !clipId;
      const isPlaying = playbar.isPlaying && playbar.clip?.id === clipId;

      const {
        logLikeClick,
        logDislikeClick,
        logShareClick,
        logSignUpTriggered,
      } = useSongPreviewAnalytics({
        clipId,
        title,
        styles,
        isPlaying,
      });

      // Set up playbar and keep clip data updated
      useEffect(() => {
        if (!clip?.id) return;

        clips.updateClips([clip]);

        const storedClip = clips.clipById[clip.id];
        if (storedClip) {
          queueStore.setPlayContext({
            clips: [clip],
            contextType: ContextType.Song,
            contextId: clip.id,
          });

          playbar.clip = storedClip;
          playbar.setNoClipPlayCallback(() => {
            const currentClip = clips.clipById[clip.id];
            if (currentClip) {
              playbar.playClip(currentClip);
            }
          });
          playbar.setIsClipPreloaded(true);
        }

        return () => {
          playbar.setIsClipPreloaded(false);
        };
      }, [clip, clips, queueStore, playbar]);

      useEffect(() => {
        if (isPlaying) {
          wasPlayingRef.current = true;
        } else if (wasPlayingRef.current) {
          if (playbar.currentTime >= SIGNUP_PLAYBACK_THRESHOLD) {
            logSignUpTriggered('auto_30s', false);
            onSignUp();
          }
          wasPlayingRef.current = false;
        }
      }, [isPlaying, playbar.currentTime, logSignUpTriggered, onSignUp]);

      const handlePlayPause = () => {
        if (
          playbar.clip?.id === clipId &&
          !playbar.isClipPreloaded &&
          audioUrl
        ) {
          playbar.togglePlay();
        } else if (audioUrl) {
          playbar.noClipPlayCallback?.();
        }
      };

      const handleLike = () => {
        logLikeClick();
        logSignUpTriggered('like', isPlaying);
        onSignUp();
      };

      const handleDislike = () => {
        logDislikeClick();
        logSignUpTriggered('dislike', isPlaying);
        onSignUp();
      };

      const handleShare = () => {
        logShareClick();
        logSignUpTriggered('share', isPlaying);
        onSignUp();
      };

      return (
        <AnimatePresence mode='wait'>
          {requireSignUp ? (
            <SongPreviewCardSignUpRequired
              key='signup-required'
              onSignUp={onSignUp}
              logSignUpTriggered={logSignUpTriggered}
            />
          ) : isLoading ? (
            <LoadingPreviewCard key='loading' />
          ) : (
            <SongPreviewCard
              key='preview'
              clipId={clipId}
              title={title}
              imageUrl={imageUrl}
              styles={styles}
              isPlaying={isPlaying}
              currentTime={playbar.currentTime}
              audioUrl={audioUrl}
              onPlayPause={handlePlayPause}
              onLike={handleLike}
              onDislike={handleDislike}
              onShare={handleShare}
              onSignUp={onSignUp}
              signUpToListen={signUpToListen}
              logSignUpTriggered={logSignUpTriggered}
            />
          )}
        </AnimatePresence>
      );
    }
  );
