/* 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 { useCallback, useEffect, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import ImageWithFallback from '@/components/image/ImageWithFallback';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import {
  ChevronDownIcon,
  ChevronUpIcon,
  EditIcon,
  PauseIcon,
  PlayIcon,
} from '@/icons';
import { ContextType } from '@/logging/contextTypes';
import logWebUserEvent from '@/logging/logWebUserEvent';

import { useChatStore } from '../../stores';
import { ReferenceType } from '../input/ReferenceTypes';

const TrackItem = observer(
  ({
    clipId,
    index,
    isPlaying,
    onPlay,
  }: {
    clipId: string;
    index: number;
    isPlaying: boolean;
    onPlay: (clipId: string) => void;
  }) => {
    const { clips } = useStores();
    const clip = clips.clipById[clipId];

    if (!clip) {
      return (
        <div className='flex h-12 items-center gap-3 px-4'>
          <SpinnerSVG className='h-4 w-4' />
          <span className='text-sm text-foreground-primary/60'>Loading...</span>
        </div>
      );
    }

    const formatDuration = (seconds: number) => {
      const mins = Math.floor(seconds / 60);
      const secs = Math.floor(seconds % 60);
      return `${mins}:${secs.toString().padStart(2, '0')}`;
    };

    return (
      <div
        className={clsx(
          'flex h-12 cursor-pointer items-center gap-3 px-4 transition-colors hover:bg-background-fog-thin/30',
          {
            'bg-background-fog-thin/20': isPlaying,
          }
        )}
        onClick={() => onPlay(clipId)}
      >
        {/* Track number */}
        <div className='flex w-6 items-center justify-center text-xs text-foreground-primary/60'>
          {isPlaying ? (
            <div className='h-2 w-2 rounded-full bg-primary' />
          ) : (
            index + 1
          )}
        </div>

        {/* Thumbnail */}
        <div className='h-8 w-8 flex-shrink-0 overflow-hidden rounded'>
          <ImageWithFallback
            src={clip.image_url}
            alt={clip.title || 'Track'}
            className='h-full w-full object-cover'
          />
        </div>

        {/* Track info */}
        <div className='min-w-0 flex-1'>
          <div className='truncate text-sm font-medium text-foreground-primary'>
            {clip.title}
          </div>
          <div className='text-xs text-foreground-primary/60'>
            {formatDuration(clip.metadata?.duration || 0)}
          </div>
        </div>

        {/* Play button */}
        <Button
          shape={ButtonShape.Pill}
          size={ButtonSize.Mini}
          icon={isPlaying ? PauseIcon : PlayIcon}
          onClick={(e) => {
            e.stopPropagation();
            onPlay(clipId);
          }}
          className='opacity-0 transition-opacity group-hover:opacity-100'
        />
      </div>
    );
  }
);

const PlaylistItem = observer(({ playlistId }: { playlistId: string }) => {
  const { clips, queue, playbar } = useStores();
  const chatStore = useChatStore();
  const [isExpanded, setIsExpanded] = useState(false);
  const [showAllTracks, setShowAllTracks] = useState(false);

  // Get playlist data
  const playlist = clips.playlistById[playlistId];

  // Load playlist data if not already loaded
  useEffect(() => {
    if (!playlist && playlistId) {
      clips.loadPlaylist(playlistId, 0, undefined, true);
    }
  }, [playlistId, playlist, clips]);

  // Check if this playlist is currently playing
  const isPlaylistPlaying =
    playbar.clip?.id && playlist?.clipIds?.includes(playbar.clip.id);
  const isPlaylistPaused = isPlaylistPlaying && !playbar.isPlaying;

  const handlePlayPauseClick = useCallback(async () => {
    if (!playlist) return;

    // Make sure we have the full playlist loaded
    if (!clips.playlistById[playlistId]) {
      await clips.loadPlaylist(playlistId, 0, undefined, true);
    }

    const currentPlaylist = clips.playlistById[playlistId];
    if (!currentPlaylist) return;

    // If playlist is currently playing, toggle play/pause
    if (isPlaylistPlaying) {
      playbar.togglePlay();
    } else {
      // Set the playlist context and play the first clip
      let playlistClips: any[] = [];

      if (currentPlaylist.playlist_clips) {
        playlistClips = currentPlaylist.playlist_clips.map(
          (pc: any) => pc.clip
        );
      } else if (currentPlaylist.clipIds) {
        playlistClips = currentPlaylist.clipIds
          .map((clipId: string) => clips.clipById[clipId])
          .filter(Boolean);
      }

      // Set as current context and play
      queue.setPlayContext({
        contextType: ContextType.Playlist,
        contextId: currentPlaylist.id,
        clips: playlistClips,
        currentIndex: 0,
        surfaceType: 'orpheus_chat',
        surfaceId: 'playlist_message',
      });

      // Play the first clip in the playlist
      if (currentPlaylist.playlist_clips && currentPlaylist.playlist_clips[0]) {
        const firstClip = currentPlaylist.playlist_clips[0].clip;
        if (firstClip?.audio_url) {
          playbar.playClip(firstClip);
        }
      } else if (playlistClips[0]) {
        const firstClip = playlistClips[0];
        if (firstClip?.audio_url) {
          playbar.playClip(firstClip);
        }
      }
    }

    logWebUserEvent({
      actionName: 'PlaylistActionPlayClicked',
      principalObjectValue: playlistId,
      principalObjectType: 'playlist',
      context: {
        isPlaying: !isPlaylistPlaying,
        trackCount: currentPlaylist.clipIds?.length || 0,
      },
    });
  }, [playlist, playlistId, clips, queue, playbar, isPlaylistPlaying]);

  const handleTrackPlay = useCallback(
    (clipId: string) => {
      const clip = clips.clipById[clipId];
      if (!clip) return;

      // If this track is already playing, toggle play/pause
      if (playbar.clip?.id === clipId) {
        playbar.togglePlay();
      } else {
        // Play this specific track
        playbar.playClip(clip);
      }
    },
    [clips, playbar]
  );

  const handleAddToReferences = useCallback(() => {
    if (!playlist) return;

    chatStore.addReference({
      type: ReferenceType.PLAYLIST,
      playlistId: playlist.id,
      name: playlist.name || 'Untitled Playlist',
      trackCount: playlist.clipIds?.length || 0,
    });

    logWebUserEvent({
      actionName: 'PlaylistActionReferenceAdded',
      principalObjectValue: playlistId,
      principalObjectType: 'playlist',
      context: {
        trackCount: playlist.clipIds?.length || 0,
      },
    });
  }, [playlist, playlistId, chatStore]);

  if (!playlist) {
    return (
      <div className='flex h-16 items-center justify-center rounded-lg border border-white/10 bg-background-fog-thin/80 backdrop-blur-sm'>
        <SpinnerSVG />
      </div>
    );
  }

  const trackCount = playlist.clipIds?.length || 0;
  const coverImage = playlist.clipIds?.[0]
    ? clips.clipById[playlist.clipIds[0]]?.image_url
    : undefined;

  return (
    <div className='group overflow-hidden rounded-lg border border-white/10 bg-background-fog-thin/80 backdrop-blur-sm'>
      {/* Playlist Header */}
      <div className='flex items-center gap-3 p-4'>
        {/* Cover Image */}
        <div className='h-12 w-12 flex-shrink-0 overflow-hidden rounded-lg'>
          {coverImage ? (
            <ImageWithFallback
              src={coverImage}
              alt={`Cover for ${playlist.name}`}
              className='h-full w-full object-cover'
            />
          ) : (
            <div className='flex h-full w-full items-center justify-center bg-background-smoke-dense/50'>
              <span className='text-xs text-foreground-primary/40'>🎵</span>
            </div>
          )}
        </div>

        {/* Playlist Info */}
        <div className='min-w-0 flex-1'>
          <h3 className='truncate text-sm font-semibold text-foreground-primary'>
            {playlist.name || 'Untitled Playlist'}
          </h3>
          <p className='text-xs text-foreground-primary/60'>
            {trackCount} {trackCount === 1 ? 'track' : 'tracks'}
          </p>
        </div>

        {/* Action Buttons */}
        <div className='flex items-center gap-2'>
          <Button
            shape={ButtonShape.Pill}
            size={ButtonSize.Mini}
            variant={ButtonVariant.Tertiary}
            icon={EditIcon}
            onClick={handleAddToReferences}
            className='opacity-0 transition-opacity group-hover:opacity-100'
          />
          <button
            onClick={handlePlayPauseClick}
            className='flex h-8 w-8 items-center justify-center rounded-full bg-transparent transition-colors hover:bg-white/10'
          >
            {isPlaylistPlaying && !isPlaylistPaused ? (
              <PauseIcon className='h-5 w-5 text-white' />
            ) : (
              <PlayIcon className='h-5 w-5 text-white' />
            )}
          </button>
          <Button
            shape={ButtonShape.Pill}
            size={ButtonSize.Mini}
            variant={ButtonVariant.Tertiary}
            icon={isExpanded ? ChevronUpIcon : ChevronDownIcon}
            onClick={() => setIsExpanded(!isExpanded)}
            className='opacity-0 transition-opacity group-hover:opacity-100'
          />
        </div>
      </div>

      {/* Track List */}
      {isExpanded && (
        <div className='border-t border-white/10 bg-background-fog-thin/40'>
          {playlist.clipIds
            ?.slice(0, showAllTracks ? Math.min(trackCount, 10) : 5)
            .map((clipId, index) => (
              <TrackItem
                key={clipId}
                clipId={clipId}
                index={index}
                isPlaying={playbar.clip?.id === clipId && playbar.isPlaying}
                onPlay={handleTrackPlay}
              />
            ))}
          {trackCount > 5 && !showAllTracks && (
            <button
              onClick={() => setShowAllTracks(true)}
              className='w-full px-4 py-2 text-center text-xs text-foreground-primary/60 transition-colors hover:bg-background-fog-thin/20 hover:text-foreground-primary'
            >
              +{trackCount - 5} more tracks
            </button>
          )}
          {showAllTracks && trackCount > 5 && trackCount <= 10 && (
            <button
              onClick={() => setShowAllTracks(false)}
              className='w-full px-4 py-2 text-center text-xs text-foreground-primary/60 transition-colors hover:bg-background-fog-thin/20 hover:text-foreground-primary'
            >
              Show less
            </button>
          )}
          {showAllTracks && trackCount > 10 && (
            <button
              onClick={() => {
                // Redirect to playlist page
                window.open(`/playlist/${playlistId}`, '_blank');
              }}
              className='w-full px-4 py-2 text-center text-xs text-foreground-primary/60 transition-colors hover:bg-background-fog-thin/20 hover:text-foreground-primary'
            >
              View all {trackCount} tracks →
            </button>
          )}
        </div>
      )}
    </div>
  );
});

export const PlaylistMessage = ({ playlistIds }: { playlistIds: string[] }) => {
  return (
    <div className='w-full px-8 py-4'>
      {/* Playlist Cards */}
      <div className='space-y-3'>
        {playlistIds.map((playlistId: string) => (
          <PlaylistItem playlistId={playlistId} key={playlistId} />
        ))}
      </div>
    </div>
  );
};
