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

/* eslint jsx-a11y/no-static-element-interactions: warn */
import { observer } from 'mobx-react-lite';
import { useCallback, useEffect, useMemo } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
// Button components removed - no longer needed
import ImageWithFallback from '@/components/image/ImageWithFallback';
import { useFetchClip } from '@/hooks/useClip';
import { useContextSelector } from '@/hooks/useContextSelector';
import { CloseIcon, PauseIcon, PlayIcon, TrashIcon } from '@/icons';
import { ContextType } from '@/logging/contextTypes';
import type { Clip } from '@/state/clipStore';
import { LARGE_IMAGE } from '@/utils/constants';

import CreateFormContext from '../../v2/CreateFormContext';
import { ConditionTypes, CreateModes } from '../../v2/types';

export const InspirationCard = observer(() => {
  const { clips, queue, playbar, session, createV2 } = useStores();
  const fetchClip = useFetchClip();

  const untimedConditions = useContextSelector(
    CreateFormContext,
    (context) => context.state.global.untimedConditions
  );

  const removeInspirationClip = useContextSelector(
    CreateFormContext,
    (context) => context.removeInspirationClip
  );

  const clearInspirationClips = useContextSelector(
    CreateFormContext,
    (context) => context.clearInspirationClips
  );

  const setState = useContextSelector(
    CreateFormContext,
    (context) => context.setState
  );

  // Get inspiration clips from individual clip IDs
  const inspirationClipIds = useMemo(
    () => untimedConditions[ConditionTypes.INSPIRATION]?.clipIds || [],
    [untimedConditions[ConditionTypes.INSPIRATION]?.clipIds]
  );

  // Get inspiration clips from legacy playlist condition
  const playlistCondition = untimedConditions[ConditionTypes.PLAYLIST];
  const playlistId = playlistCondition?.playlistId;
  const playlist =
    playlistId &&
    createV2.conditioningPlaylist &&
    createV2.conditioningPlaylist.id === playlistId
      ? createV2.conditioningPlaylist
      : playlistId
        ? clips.playlistById[playlistId]
        : null;

  // Get random 4 songs from playlist using stable Fisher-Yates shuffle
  const playlistClipIds = useMemo(() => {
    if (!playlist?.playlist_clips?.length || !session.userId) return [];

    const ownedClips = playlist.playlist_clips.filter((playlistClip) => {
      const clip = playlistClip.clip;
      return clip?.id && clip.user_id === session.userId;
    });

    if (!ownedClips.length) return [];

    // Create a copy and use Fisher-Yates shuffle for uniform randomness
    const shuffled = [...ownedClips];
    for (let i = shuffled.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
    }

    const selectedClipIds: string[] = [];
    shuffled.slice(0, 4).forEach((playlistClip) => {
      const clipId = playlistClip.clip?.id;
      if (clipId) {
        selectedClipIds.push(clipId);
      }
    });

    return selectedClipIds;
  }, [playlist?.playlist_clips, session.userId]); // Only re-shuffle when playlist clips change

  // Combine both sources of clip IDs
  const uniqueClipIds = useMemo(() => {
    const allInspirationClipIds = [...inspirationClipIds, ...playlistClipIds];
    return Array.from(new Set(allInspirationClipIds)).slice(0, 4);
  }, [inspirationClipIds, playlistClipIds]);

  // Get clip data from store
  const inspirationClips = uniqueClipIds
    .map((clipId) => clips.clipById?.[clipId])
    .filter(Boolean); // Remove any undefined clips

  // Track missing clips that need to be fetched
  const missingClipIds = useMemo(
    () => uniqueClipIds.filter((clipId) => !clips.clipById?.[clipId]),
    [uniqueClipIds, clips.clipById]
  );

  // Fetch missing clips
  useEffect(() => {
    missingClipIds.forEach((clipId) => {
      fetchClip(clipId, false); // Don't poll, just fetch once
    });
  }, [missingClipIds, fetchClip]);

  const handlePlayClip = useCallback(
    (clip: Clip, index: number) => {
      const isCurrentlyPlaying =
        playbar.isPlaying &&
        queue.isPlayingAt({
          contextType: ContextType.Create,
          contextId: 'inspiration',
          queueType: 'context',
          index,
        });

      if (isCurrentlyPlaying) {
        playbar.togglePlay();
      } else {
        // Set up playlist context with inspiration clips
        queue.setPlayContext({
          contextType: ContextType.Create,
          contextId: 'inspiration',
          clips: inspirationClips,
          currentIndex: index,
        });
        playbar.playClip(clip);
      }
    },
    [queue, playbar, inspirationClips]
  );

  const handleRemoveClip = useCallback(
    (clipId: string) => {
      // If this clip comes from individual inspiration clips, remove it normally
      if (inspirationClipIds.includes(clipId)) {
        removeInspirationClip(clipId);
      }
      // If this clip comes from a playlist, convert playlist to individual clips and remove the specific one
      else if (playlistClipIds.includes(clipId)) {
        setState((prevState) => {
          // Convert all playlist clips to individual clips, excluding the one being removed
          const remainingPlaylistClips = playlistClipIds.filter(
            (id) => id !== clipId
          );
          const allClips = [...inspirationClipIds, ...remainingPlaylistClips];

          return {
            ...prevState,
            global: {
              ...prevState.global,
              untimedConditions: {
                ...prevState.global.untimedConditions,
                [ConditionTypes.PLAYLIST]: undefined, // Clear playlist condition
                [ConditionTypes.INSPIRATION]:
                  allClips.length > 0 ? { clipIds: allClips } : undefined, // Set individual clips
              },
            },
          };
        });
      }
    },
    [removeInspirationClip, inspirationClipIds, playlistClipIds, setState]
  );

  const handleClearAll = useCallback(() => {
    // Clear individual inspiration clips
    clearInspirationClips();

    // Clear playlist condition and title if it exists
    if (playlistCondition) {
      setState((prevState) => ({
        ...prevState,
        global: {
          ...prevState.global,
          untimedConditions: {
            ...prevState.global.untimedConditions,
            [ConditionTypes.PLAYLIST]: undefined,
          },
        },
        [CreateModes.CUSTOM]: {
          ...prevState[CreateModes.CUSTOM],
          title: '',
        },
      }));
    }
  }, [clearInspirationClips, playlistCondition, setState]);

  // Early return if no inspiration clips from either source - must be after all hooks
  if (!uniqueClipIds.length) {
    return null;
  }

  return (
    <div className='relative w-full overflow-hidden rounded-[16px]'>
      <div className='flex w-full flex-col'>
        {/* Header with title and clear button */}
        <div className='flex items-center justify-between bg-white/[0.04] px-4 pt-4 pb-2'>
          <div className='text-[16px] leading-[24px] font-medium text-white'>
            Inspiration{' '}
            <span
              className={`text-[12px] leading-[16px] font-normal tracking-[0.24px] ${
                inspirationClips.length === 4
                  ? 'text-accent-red'
                  : 'text-foreground-tertiary'
              }`}
            >
              ({inspirationClips.length}/4)
            </span>
          </div>
          <div
            className='size-4 cursor-pointer'
            onClick={handleClearAll}
            title='Clear all inspiration'
            role='button'
            aria-label='Clear all inspiration clips'
            tabIndex={0}
            onKeyDown={(e) => {
              if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault();
                handleClearAll();
              }
            }}
          >
            <TrashIcon className='size-full text-foreground-tertiary' />
          </div>
        </div>

        {/* Individual song list */}
        <div className='flex w-full flex-col'>
          {inspirationClips.map((clip, index) => {
            const isCurrentlyPlaying =
              playbar.isPlaying &&
              queue.isPlayingAt({
                contextType: ContextType.Create,
                contextId: 'inspiration',
                queueType: 'context',
                index,
              });

            // isHovered removed - not needed in new design

            return (
              <div
                key={clip.id}
                className='flex h-14 items-center justify-between bg-white/[0.04] px-4 py-0'
              >
                <div className='flex min-w-0 flex-1 items-center gap-2'>
                  {/* Song artwork */}
                  <div
                    className='group relative size-10 flex-shrink-0 cursor-pointer overflow-hidden rounded-[12px] bg-black/50'
                    onClick={() => handlePlayClip(clip, index)}
                    title={`Play "${clip.title}"`}
                  >
                    <ImageWithFallback
                      imageSize={LARGE_IMAGE}
                      className='h-full w-full object-cover'
                      src={clip.image_url}
                      alt={`Cover art for ${clip.title}`}
                    />
                    {/* Play/Pause button overlay */}
                    <div className='absolute top-1/2 left-1/2 size-4 -translate-x-1/2 -translate-y-1/2'>
                      {isCurrentlyPlaying ? (
                        <PauseIcon className='h-4 w-4 text-white' />
                      ) : (
                        <PlayIcon className='h-4 w-4 text-white' />
                      )}
                    </div>
                  </div>

                  {/* Song title */}
                  <div className='min-w-0 truncate text-[14px] leading-[22px] font-medium text-foreground-primary'>
                    {clip.title || `Untitled Song ${index + 1}`}
                  </div>
                </div>

                {/* Remove individual song button */}
                <div
                  className='size-4 flex-shrink-0 cursor-pointer'
                  onClick={() => handleRemoveClip(clip.id)}
                  title='Remove this song'
                  role='button'
                  aria-label={`Remove ${clip.title || `Untitled Song ${index + 1}`} from inspiration`}
                  tabIndex={0}
                  onKeyDown={(e) => {
                    if (e.key === 'Enter' || e.key === ' ') {
                      e.preventDefault();
                      handleRemoveClip(clip.id);
                    }
                  }}
                >
                  <CloseIcon className='size-full text-foreground-tertiary' />
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
});
