import { observer } from 'mobx-react-lite';
import { usePathname, useRouter } from 'next/navigation';
import { RefObject, useEffect, useLayoutEffect } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import Button, { ButtonVariant } from '@/components/button/Button';
import {
  GridListItemWrapper,
  GridListWrapper,
} from '@/components/grid/GridListUtils';
import SongRow from '@/components/song/SongRow';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import { useBreakpointMd } from '@/hooks/useBreakpoint';
import { useLibraryClips } from '@/hooks/useLibraryClips';
import { ContextType } from '@/logging/contextTypes';
import { Clip } from '@/state/clipStore';
import { AudioUploadStatus } from '@/state/createV2Store';

export const LibraryClips = observer(
  ({ libraryRef }: { libraryRef: RefObject<any> }) => {
    const {
      library,
      playbar: playbarState,
      queue,
      edit,
      session,
      genForm,
      createV2,
      menus,
    } = useStores();
    // todo: this check shouldn't be necessary
    const isMobile = !useBreakpointMd();
    const pathname = usePathname();
    const router = useRouter();

    const { isLoading } = useLibraryClips();

    useEffect(() => {
      if (session.flags?.configs) {
        genForm.loadAdvancedParams();
      }
    }, [session.userId]);

    useLayoutEffect(() => {
      if (
        libraryRef?.current &&
        edit.pendingScrollPositionChange &&
        edit.pendingScrollPositionChange.page === 'library'
      ) {
        libraryRef.current.scrollTo({
          top: edit.pendingScrollPositionChange.scrollPosition,
        });
      } else if (edit.pendingScrollPositionChange) {
        edit.setPendingScrollPositionChange(null);
      }
    }, [
      libraryRef.current,
      edit.pendingScrollPositionChange,
      library.currentClips,
    ]);

    return (
      <>
        <div
          className='flex-1 overflow-y-auto'
          style={{ marginLeft: isMobile ? '1rem' : 0 }}
          ref={libraryRef}
        >
          {isLoading ? (
            <div className='flex justify-center pt-[60px]'>
              <SpinnerSVG />
            </div>
          ) : library.currentClips?.length === 0 ? (
            <div className='flex flex-col justify-center px-6'>
              <p className='text-foreground-secondary'>
                No songs matching filters.
              </p>
              <Button
                variant={ButtonVariant.Standard}
                onClick={() => {
                  router.push(`/create`);
                }}
              >
                Create Song
              </Button>
            </div>
          ) : (
            <>
              {createV2.audioUploadStatus === AudioUploadStatus.UPLOADING &&
              library.filters.clips.page === 0 ? (
                <SongRow
                  expanded={true}
                  showStats={false}
                  selected={false}
                  key={'pending-upload-clip'}
                  clip={
                    {
                      title:
                        createV2.audioUploadPendingClip?.title ?? 'Untitled',
                      metadata: {},
                    } as Clip
                  }
                  onClick={() => {}}
                  onPlay={() => {}}
                  isLoading
                />
              ) : null}
              <GridListWrapper
                aria-label={`${(library.currentClips || []).length} Clips`}
                items={library.currentClips || []}
              >
                {(clip: Clip) => {
                  return (
                    <GridListItemWrapper>
                      <SongRow
                        key={clip.id}
                        contextType={ContextType.Library}
                        contextId='library'
                        onClick={() => {}}
                        selected={[...(menus.selected || [])].includes(clip.id)}
                        onPlay={() => {
                          if (
                            queue.contextType === ContextType.Library &&
                            playbarState.clip?.id === clip.id
                          ) {
                            playbarState.togglePlay();
                            return;
                          }
                          queue.setPlayContext({
                            clips: library.currentClips || [],
                            currentIndex: (
                              library.currentClips || []
                            ).findIndex((c: Clip) => c.id === clip.id),
                            contextType: ContextType.Library,
                            contextId: 'library',
                          });
                          playbarState.playClip(clip);
                        }}
                        onTriggerEditMode={() => {
                          const libraryScrollPosition =
                            libraryRef.current?.scrollTop || 0;
                          edit.resetEditState();
                          edit.setExitEditModeCallback(() => {
                            router.push(pathname);
                            edit.setPendingScrollPositionChange({
                              page: 'library',
                              scrollPosition: libraryScrollPosition || 0,
                            });
                          });
                        }}
                        clip={clip}
                      />
                    </GridListItemWrapper>
                  );
                }}
              </GridListWrapper>
            </>
          )}
        </div>
      </>
    );
  }
);

export default LibraryClips;
