'use client';

import { useInfiniteQuery } from '@tanstack/react-query';
import { observer } from 'mobx-react-lite';
import { useRouter } from 'next/navigation';
import { useMemo } from 'react';
import { useInView } from 'react-intersection-observer';

import { useStores } from '@/app/(root)/AppProviders';
import Button from '@/components/button/Button';
import SongList from '@/components/song/Songlist';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import { useApiClient } from '@/lib/apiClient';
import { ContextType } from '@/logging/contextTypes';
import { Clip } from '@/state/clipStore';
import { DEFAULT_PAGE_SIZE } from '@/utils/constants';

const ListeningHistoryClips = observer(() => {
  const { clips } = useStores();
  const router = useRouter();
  const apiClient = useApiClient();

  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isLoading,
    error,
  } = useInfiniteQuery({
    queryKey: ['listen-history'],
    queryFn: async ({ pageParam }) => {
      const response = await apiClient.GET('/api/profiles/listen-history', {
        params: {
          query: { cursor: pageParam, limit: DEFAULT_PAGE_SIZE },
        },
      });
      if (!response.data) throw new Error('Failed to fetch listen history');

      const data = response.data;

      // Update clips store with fetched data
      const clipContents = data.history
        ?.map((item) => item?.content)
        .filter(Boolean);

      if (clipContents?.length > 0) {
        clips.updateClips(clipContents as Clip[]);
      }

      return data;
    },
    initialPageParam: null as string | null,
    getNextPageParam: (lastPage) => lastPage.next_cursor || undefined,
    select(data) {
      const processedData = {
        ...data.pages[data.pages.length - 1],
        num_pages: data.pages.length,
        history: data.pages
          .flatMap((page) => page?.history)
          .filter((v) => v != null),
      };
      return processedData as NonNullable<typeof processedData>;
    },
    staleTime: 30000,
  });

  const listenHistory = useMemo(() => {
    if (!data?.history) return [];

    // Return clip objects from store
    return data.history
      .map((item) => clips.clipById[item.content.id])
      .filter(Boolean);
  }, [data, clips]);

  const { ref: spinnerRef } = useInView({
    threshold: 0,
    onChange: (inView) => {
      if (inView && hasNextPage && !isFetchingNextPage) {
        fetchNextPage();
      }
    },
  });

  if (error) {
    return (
      <div className='flex h-full flex-col items-center justify-center pt-10'>
        <span className='mb-4 text-foreground-secondary'>
          Failed to load listening history
        </span>
        <Button onClick={() => window.location.reload()}>Retry</Button>
      </div>
    );
  }

  return (
    <div className='flex h-full flex-col overflow-y-hidden'>
      {isLoading ? (
        <div className='flex h-full items-center justify-center'>
          <SpinnerSVG />
        </div>
      ) : listenHistory.length > 0 ? (
        <>
          <SongList
            songs={listenHistory}
            playlistId='listen-history'
            contextId=''
            contextType={ContextType.History}
            isLoading={isFetchingNextPage}
            showPreview={false}
            songRowProps={{
              showStats: true,
              showActions: true,
              isFromSongRow: false,
              stream: false,
              trendingMode: false,
              showUser: false,
              showModelTagOnly: true,
            }}
            enableInfiniteScroll={false}
          />
          {hasNextPage && !isFetchingNextPage && (
            <div className='flex w-full justify-center'>
              <SpinnerSVG ref={spinnerRef} />
            </div>
          )}
        </>
      ) : (
        <div className='mt-20 flex w-full flex-col items-center justify-center gap-8'>
          <span className='text-md w-[80%] justify-center text-center font-sans text-foreground-secondary'>
            Your listen history is empty. Start listening to songs to see them
            here
          </span>
          <Button onClick={() => router.push('/')}>Back to Home Page</Button>
        </div>
      )}
    </div>
  );
});

export default ListeningHistoryClips;
