'use client';

import { observer } from 'mobx-react-lite';

import { useStores } from '@/app/(root)/AppProviders';
import {
  GridListItemWrapper,
  GridListWrapper,
} from '@/components/grid/GridListUtils';
import { default as SongRow, SongRowUIProps } from '@/components/song/SongRow';
import { ContextType } from '@/logging/contextTypes';
import { Clip } from '@/state/clipStore';

import SpinnerSVG from '../svg/SpinnerSVG';

const DEFAULT_RELOAD_THRESHOLD = 7;
interface SonglistProps {
  // Data props
  songs: Clip[]; // a list of songs to display
  enableInfiniteScroll?: boolean; // enable infinite scroll for loading more songs
  infiniteScrollLoadingRef?: React.Ref<HTMLDivElement>; // the loading reference on the page to trigger loading more songs
  contextId: string; // the context id for play context in UI, playbar
  contextType: ContextType; // the context type for play context in playbar
  playlistId: string; // the playlist id for play context in UI, playbar

  // UI props
  isLoading?: boolean; // indicate whether the list is loading more songs for UI indication.

  // TODO: remove these props
  showPreview?: boolean; // show the preview of the song when clicked
  useNewSongRow?: boolean;

  // Song row props for UI customization
  songRowProps?: SongRowUIProps;
}

// This is the song list component that displays the list of songs for general uses.
// It can be used in the search, tag pages to display the list of songs without drag/drop ordering changes.
const SongList: React.FC<SonglistProps> = observer(
  ({
    songs = [],
    playlistId,
    enableInfiniteScroll = true,
    infiniteScrollLoadingRef: loadingRef,
    contextId,
    contextType,
    isLoading = false,
    songRowProps = {
      stream: false,
      showStats: true,
      showTags: false,
      trendingMode: true,
      showActions: true,
      showUser: true,
      isFromSongRow: false,
      showTimer: false,
      rankingMode: false,
    },
  }) => {
    const { playbar, menus, queue: queueStore } = useStores();

    return (
      <div className='sticky top-0 mb-4 w-full overflow-y-auto'>
        <div className='flex overflow-y-auto'>
          <div className='flex w-full flex-col overflow-y-auto'>
            <GridListWrapper
              aria-label={`${songs.length} Songs`}
              items={
                songs.map((c: Clip, index: number) => ({
                  id: c.id,
                  index,
                  clip: c,
                })) || []
              }
            >
              {(songObj: any) => (
                <GridListItemWrapper
                  key={songObj.id}
                  aria-label={songObj.title || 'Untitled Song'}
                >
                  {enableInfiniteScroll &&
                    !!loadingRef &&
                    songObj.index ===
                      songs.length - DEFAULT_RELOAD_THRESHOLD && (
                      <div ref={loadingRef} />
                    )}
                  <SongRow
                    key={songObj.id}
                    clip={songObj.clip}
                    showTags={songRowProps.showTags}
                    showModelTagOnly={songRowProps.showModelTagOnly}
                    selected={songObj?.id === menus.currentClip?.id}
                    onClick={(e) => {
                      if (e.target.tagName === 'BUTTON') return;
                      menus.setCurrentClip(songObj.clip);
                    }}
                    index={songObj.index}
                    playlistId={playlistId}
                    contextType={contextType}
                    contextId={contextId}
                    rankingMode={songRowProps.rankingMode}
                    sectionName={contextId}
                    onPlay={() => {
                      if (playbar.clip?.id === songObj.id) {
                        playbar.togglePlay();
                        return;
                      }
                      queueStore.setPlayContext({
                        contextType: contextType,
                        contextId: contextId,
                        clips: songs,
                        currentIndex: songObj.index,
                      });
                      playbar.playClip(songObj.clip);
                    }}
                    {...songRowProps}
                  />
                </GridListItemWrapper>
              )}
            </GridListWrapper>
            {isLoading && (
              <div className='mt-4 flex items-center justify-center'>
                <SpinnerSVG />
              </div>
            )}
          </div>
        </div>
      </div>
    );
  }
);

export default SongList;
