'use client';

/* eslint jsx-a11y/click-events-have-key-events: warn */

/* eslint jsx-a11y/no-static-element-interactions: warn */
import clsx from 'clsx';
import { observer } from 'mobx-react-lite';
import { useRouter } from 'next/navigation';
import { memo, useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { useStores } from '@/app/(root)/AppProviders';
import ImpressionLogger from '@/components/ImpressionLogger';
import { ImpressionLoggerConfig } from '@/components/ImpressionLogger';
import ImageWithFallback from '@/components/image/ImageWithFallback';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import usePlaySource from '@/hooks/usePlaySource';
import { StatefulPlayPauseIcon } from '@/icons';
import { useApiClient } from '@/lib/apiClient';
import { components } from '@/lib/gen';
import { ContextType } from '@/logging/contextTypes';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { SMALL_IMAGE } from '@/utils/constants';

export type ShortcutType = components['schemas']['ShortcutType'];
type ShortcutContext = components['schemas']['ShortcutContext'];

const ShortcutComponent = ({
  imageUrl,
  title,
  description,
  isPlaying,
  isCurrentContext,
  onClick,
  onPlayClick,
  isLoading,
}: {
  imageUrl: string;
  title: string;
  description: string;
  isPlaying: boolean;
  isCurrentContext: boolean;
  isLoading: boolean;
  onClick: () => void;
  onPlayClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
}) => {
  const { t } = useTranslation();
  return (
    <div
      className={clsx(
        'flex h-full items-center hover:cursor-pointer',
        'flex w-full flex-row items-center justify-between rounded-lg',
        'bg-background-secondary text-foreground-primary hover:bg-background-tertiary'
      )}
      onClick={onClick}
      data-media-playing={isPlaying}
    >
      <div className='flex w-60 cursor-pointer flex-row items-center gap-1 rounded-lg'>
        <div className='shrink-0 rounded-lg'>
          <button
            className='group relative m-1.5 shrink-0'
            onClick={onPlayClick}
            aria-label={isPlaying ? t('media.pause') : t('media.play')}
          >
            <ImageWithFallback
              className='h-12 w-12 rounded-lg object-cover'
              src={imageUrl}
              alt={title}
              imageSize={SMALL_IMAGE}
            />
            <div
              className={clsx(
                'absolute inset-0 flex items-center justify-center rounded-lg',
                'transition-colors duration-150',
                'group-hover:bg-opacity-black-30 group-hover:text-foreground-primary-glass',
                'group-focus-within:bg-opacity-black-30 group-focus-within:text-foreground-primary-glass',
                {
                  'bg-transparent text-transparent': !(
                    isPlaying || isCurrentContext
                  ),
                  'bg-opacity-black-30 text-foreground-primary-glass':
                    isPlaying || isCurrentContext,
                }
              )}
            >
              <StatefulPlayPauseIcon className='h-6 w-6' />
            </div>
            {isLoading && (
              <div className='absolute inset-0 flex items-center justify-center'>
                <SpinnerSVG className='h-6 w-6' />
              </div>
            )}
          </button>
        </div>
        <div className='flex min-w-0 flex-col gap-0.5'>
          <div className='line-clamp-1 font-sans text-sm leading-4 font-medium text-ellipsis text-foreground-primary'>
            {title}
          </div>
          <div className='line-clamp-1 pr-2 font-sans text-xs leading-4 font-medium text-ellipsis text-foreground-tertiary'>
            {description}
          </div>
        </div>
      </div>
    </div>
  );
};

export const ShortcutItem = memo(
  observer(function ShortcutItem({
    id,
    imageUrl,
    title,
    description,
    redirectUrl,
    shortcutContext,
    playlistContextId,
    index,
  }: {
    id: ShortcutType;
    imageUrl: string;
    title: string;
    description: string;
    redirectUrl: string;
    shortcutContext: ShortcutContext;
    playlistContextId: string;
    index: number;
  }) {
    const {
      queue: queueStore,
      playbar: playbarStore,
      clips: clipsStore,
    } = useStores();
    const router = useRouter();
    const apiClient = useApiClient();
    const playSource = usePlaySource();

    const [isLoading, setIsLoading] = useState(false);
    const isCurrentContext =
      queueStore.isPlaylistCurrentContext(playlistContextId);
    const isPlaying = isCurrentContext && playbarStore.isPlaying;

    const loadShortcutPlaylist = async ({
      shortcutType,
      songId,
    }: {
      shortcutType: ShortcutType;
      songId?: string | null;
    }) => {
      const response = await apiClient.GET('/api/discover/shortcuts_songs', {
        params: {
          query: {
            shortcut_type: shortcutType,
            ...(songId ? { context_song_id: songId } : {}),
          },
        },
      });
      const playlist = response.data?.playlist;
      if (playlist) {
        // update the playlist & clipStore with the shortcut playlist data
        const playlistWithClips = {
          ...playlist,
          id: playlistContextId,
          clipIds: playlist.playlist_clips
            .map((playlistClip: any) => playlistClip?.clip?.id)
            .filter((clipId: string | undefined) => clipId !== undefined),
        };
        clipsStore.updatePlaylists([playlistWithClips], 1);
        clipsStore.updateClips(playlist.playlist_clips.map((c) => c.clip));
      }
    };

    const handlePlayPauseClick = useCallback(
      (e: React.MouseEvent<HTMLButtonElement>) => {
        e.stopPropagation();
        async function loadAndPlayPlaylist() {
          // Make sure we have the playlist loaded
          if (!clipsStore.playlistById[playlistContextId]) {
            setIsLoading(true);
            await loadShortcutPlaylist({
              shortcutType: id as ShortcutType,
              songId: shortcutContext.song_id,
            });
          }
          setIsLoading(false);
          const currentPlaylist = clipsStore.playlistById[playlistContextId];
          if (queueStore.isPlaylistCurrentContext(currentPlaylist.id)) {
            // If it's the current playlist, toggle play
            playbarStore.togglePlay();
            return;
          } else {
            queueStore.setPlayContext({
              contextType: ContextType.Shortcut,
              contextId: playlistContextId,
              clips: currentPlaylist.playlist_clips.map((pc: any) => pc.clip),
              currentIndex: 0,
              surfaceType: playSource.playSourceType,
              surfaceId: playSource.playSourceId,
            });
            playbarStore.playClip(currentPlaylist.playlist_clips[0].clip);
          }

          logWebUserEvent({
            actionName: 'ShortcutItemPlayClicked',
            principalObjectType: 'homepage_shortcut',
            principalObjectValue: id,
            context: {
              index,
              title,
              description,
              shortcutContext,
            },
          });
        }
        loadAndPlayPlaylist();
      },
      [
        id,
        shortcutContext.song_id,
        playlistContextId,
        clipsStore,
        queueStore,
        playbarStore,
        playSource.playSourceType,
        playSource.playSourceId,
        description,
        title,
        index,
        loadShortcutPlaylist,
        title,
      ]
    );

    const handleClick = useCallback(() => {
      logWebUserEvent({
        actionName: 'ShortcutItemClicked',
        principalObjectType: 'homepage_shortcut',
        principalObjectValue: id,
        context: {
          index,
          title,
          description,
          shortcutContext,
        },
      });
      router.push(redirectUrl || '');
    }, [redirectUrl, router, index, title, description, shortcutContext, id]);

    const impressionLoggerConfig = useMemo<ImpressionLoggerConfig[]>(() => {
      const baseEvent = {
        principalObjectType: 'homepage_shortcut' as const,
        principalObjectValue: id,
        context: {
          index,
          title,
          description,
          shortcutContext,
        },
      };
      return [
        {
          event: {
            ...baseEvent,
            actionName: 'ShortcutItemSeen',
          },
          threshold: 0.95,
        },
        {
          event: {
            ...baseEvent,
            actionName: 'ShortcutItemSeenPartially',
          },
          threshold: 0.25,
        },
      ];
    }, [id, index, title, description, shortcutContext]);

    return (
      <ImpressionLogger configs={impressionLoggerConfig}>
        <ShortcutComponent
          imageUrl={imageUrl}
          title={title}
          description={description}
          isPlaying={isPlaying}
          isCurrentContext={isCurrentContext}
          isLoading={isLoading}
          onClick={handleClick}
          onPlayClick={handlePlayPauseClick}
        />
      </ImpressionLogger>
    );
  })
);

export default ShortcutItem;
