import { usePalette } from 'color-thief-react';
import { observer } from 'mobx-react-lite';
import { usePathname } from 'next/navigation';
import React, { useMemo, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import CardOverlayButton from '@/components/card/CardOverlayButton';
import Link from '@/components/link/Link';
import usePlaySourceContext from '@/hooks/usePlaySource';
import { ThumbsUpIcon } from '@/icons';
import { WebUserEvent } from '@/logging/TrackingEventTypes';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { ALL_AURA_IMAGE_URLS, LARGE_IMAGE } from '@/utils/constants';
import { getCountString } from '@/utils/utils';

import ImpressionLogger from '../ImpressionLogger';
import ImageWithFallback from '../image/ImageWithFallback';
import MetadataBlock from '../section/MetadataBlock';

export const useRandomAura = () => {
  const [randomImage] = useState(() => {
    return ALL_AURA_IMAGE_URLS[
      Math.floor(Math.random() * ALL_AURA_IMAGE_URLS.length)
    ];
  });

  return randomImage;
};

interface PlaylistCardProps {
  playlist: any;
  showPlaylistStats?: boolean;
  hideAvatar?: boolean;
}

const PlaylistCard: React.FC<PlaylistCardProps> = observer(
  ({ playlist, showPlaylistStats = false, hideAvatar = false }) => {
    const { library, session } = useStores();

    const playSource = usePlaySourceContext();

    const randomFallbackImage = useRandomAura();
    const pathname = usePathname();

    const [liked, setLiked] = useState(playlist?.reaction === 'L' || false);
    const [upvoteCount, setUpvoteCount] = useState(playlist?.upvote_count);
    const playlistImage =
      playlist?.image_url || playlist?.image || randomFallbackImage;

    const { data: paletteData } = usePalette(playlistImage || '', 2, 'hex', {
      crossOrigin: 'cross-origin',
    });

    const handlePlaylistReaction = async (
      e: React.MouseEvent<HTMLButtonElement>,
      reactionRequest: 'LIKE' | 'DISLIKE'
    ) => {
      e.stopPropagation();
      e.preventDefault();
      const currentReaction = liked ? 'LIKE' : 'DISLIKE';
      const newReaction =
        currentReaction === reactionRequest ? null : reactionRequest;

      setLiked(newReaction === 'LIKE');
      setUpvoteCount(upvoteCount + (newReaction === 'LIKE' ? 1 : -1));

      const { response } = await library.apiClient.POST(
        '/api/playlist_reaction/{playlist_id}/update_reaction_type/',
        {
          params: {
            path: {
              playlist_id: playlist?.id,
            },
          },
          body: {
            reaction: newReaction,
          },
        }
      );

      if (!response.ok) {
        setLiked(currentReaction === 'LIKE');
        setUpvoteCount(upvoteCount);
      }
    };

    const impressionEvent: WebUserEvent = useMemo(
      () => ({
        actionName: 'PlaylistCardSeen',
        principalObjectType: 'playlist',
        principalObjectValue: playlist?.id,
        context: {
          title: playlist?.name || playlist?.title,
          subtitle: playlist?.description,
          artistDisplayName: playlist?.user_display_name,
          usedFallbackImage: playlistImage === randomFallbackImage,

          songCount: playlist?.num_total_results,
          upvoteCount,

          isUserOwner: playlist?.owner_id === session.userId,
          isLiked: liked,

          playSourceType: playSource.playSourceType,
          playSourceId: playSource.playSourceId,
        },
      }),
      [
        playlist,
        playlistImage,
        randomFallbackImage,
        upvoteCount,
        liked,
        session.userId,
        playSource,
      ]
    );

    return (
      <ImpressionLogger
        event={impressionEvent}
        className={`${playlist?.title ? 'pb-8' : ''}`}
      >
        <div className='group flex w-40 flex-col items-center'>
          <Link
            className='flex w-full flex-col items-center'
            href={`/playlist/${playlist?.id}`}
            onClick={() => {
              logWebUserEvent({
                actionName: 'PlaylistCardTitleClicked',
                principalObjectType: 'playlist',
                principalObjectValue: playlist?.id,
                componentContext: pathname === '/me' ? 'library' : undefined,
              });
            }}
          >
            <div className='relative z-1 h-32 w-32 overflow-hidden rounded-xl transition duration-300 ease-in-out group-hover:-translate-y-1'>
              <div
                className='h-full w-full'
                style={{ backgroundColor: paletteData?.[1] }}
              ></div>
              <div className='absolute inset-0 bg-black/20'></div>
              <div className='transition-group-opacity group-hover:bg-opacity-70 absolute inset-0 bg-black/60 transition-opacity duration-1000 ease-in-out'></div>{' '}
            </div>
            <div className='relative z-2 -mt-[120px] h-36 w-36 overflow-hidden rounded-xl shadow-[0px_-2px_2px_rgba(0,0,0,0.5)] transition duration-300 ease-in-out group-hover:-translate-y-2'>
              <div
                className='h-full w-full'
                style={{ backgroundColor: paletteData?.[0] }}
              ></div>
              <div className='absolute inset-0 bg-black/20'></div>
            </div>
            <div className='relative z-3 -mt-[130px] mb-4 h-40 w-full overflow-hidden rounded-xl shadow-[0px_-2px_2px_rgba(0,0,0,0.5)] transition-transform duration-300 ease-in-out group-hover:-translate-y-3'>
              {upvoteCount !== undefined &&
              playlist?.id !== 'liked' &&
              playlist?.id !== 'sharelist' ? (
                <CardOverlayButton
                  className='absolute bottom-2 left-2'
                  contentClassName='flex-row'
                  icon={ThumbsUpIcon}
                  aria-label='Like playlist button'
                  onClick={(e) => handlePlaylistReaction(e, 'LIKE')}
                  stacked={false}
                >
                  {getCountString(upvoteCount)}
                </CardOverlayButton>
              ) : null}
              <ImageWithFallback
                className='h-40 w-full object-cover'
                imageSize={LARGE_IMAGE}
                src={playlistImage}
                alt={`Image for ${playlist?.name || playlist?.title}`}
              />
            </div>
          </Link>
          <MetadataBlock
            title={playlist?.name || playlist?.title || 'Untitled Playlist'}
            subtitle={playlist?.description || ''}
            artistTagProps={
              playlist?.user_handle || playlist?.user_id
                ? {
                    displayName: playlist?.user_display_name,
                    handle: playlist?.user_handle || playlist?.user_id,
                    imageUrl: playlist?.user_avatar_image_url,
                    showAvatar: !!playlist?.user_avatar_image_url,
                  }
                : undefined
            }
            link={`/playlist/${playlist?.id}`}
            isSongCard={false}
            isPlaylistCard={true}
            playlist={playlist}
            showPlaylistStats={showPlaylistStats}
            hideAvatar={hideAvatar}
          />
        </div>
      </ImpressionLogger>
    );
  }
);

export default PlaylistCard;
