'use client';

import { observer } from 'mobx-react-lite';
import { useEffect, useState } from 'react';
import { useInView } from 'react-intersection-observer';

import { useStores } from '@/app/(root)/AppProviders';
import GenreCard from '@/components/card/GenreCard';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import { QueryParams } from '@/state/searchStore';

import { GENRE_SEARCH_PAGE_SIZE } from './utils';

interface GenreResult {
  id: string;
  name: string;
  image_url: string;
}

const GenreSearch = observer(() => {
  const { search } = useStores();
  const [isLoading, setIsLoading] = useState(false);

  const effectiveSearchTerm = search.searchTerm || '*';

  useEffect(() => {
    const searchGenres = async () => {
      setIsLoading(true);
      await search.searchData(
        effectiveSearchTerm,
        false,
        'platform_genre',
        search.searchRankingType,
        undefined,
        undefined,
        GENRE_SEARCH_PAGE_SIZE
      );
      setIsLoading(false);
    };

    if (effectiveSearchTerm) {
      searchGenres();
    }
  }, [search, effectiveSearchTerm, search.searchRankingType]);

  const { ref: spinnerRef } = useInView({
    threshold: 0,
    rootMargin: '0px 0px 500px 0px',
    onChange: async (inView) => {
      if (inView && !isLoading) {
        setIsLoading(true);
        await search.searchData(
          effectiveSearchTerm,
          true,
          'platform_genre',
          search.searchRankingType,
          undefined,
          undefined,
          GENRE_SEARCH_PAGE_SIZE
        );
        setIsLoading(false);
      }
    },
  });

  const searchResult =
    search.searchResultCache[
      new QueryParams({
        searchType: 'platform_genre',
        query: effectiveSearchTerm,
        isPublic: true,
        rankBy: search.searchRankingType,
        fromIndex: 0,
        pageSize: GENRE_SEARCH_PAGE_SIZE,
      }).getSearchCacheKey()
    ];

  const searchResults = (searchResult?.result || []).map((result: any) => {
    return {
      id: result.genre,
      name: result.genre,
      image_url: result.image,
    };
  });

  return (
    <div
      className='sticky mr-5 ml-6 flex flex-col overflow-y-auto'
      style={{ scrollbarWidth: 'none' }}
    >
      <div className='h-16 pb-2'>
        {isLoading ? (
          <div className='flex flex-row items-center'>
            <span className='font-sans text-xl font-bold'>
              {`Searching ${
                search.searchTerm.length > 0
                  ? ` "${search.searchTerm}"`
                  : 'popular genres'
              }...`}
            </span>
            <SpinnerSVG className='ml-3' />
          </div>
        ) : searchResults.length > 0 ? (
          <span className='font-sans text-xl font-bold'>
            {search.searchTerm.length > 0
              ? `Search results for "${search.searchTerm}"`
              : 'Popular Genres:'}
          </span>
        ) : (
          <span className='font-sans text-xl font-bold'>
            {'No genres found.'}
          </span>
        )}
      </div>

      <div
        className='grid gap-8 overflow-y-auto'
        style={{
          gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))',
        }}
      >
        {searchResults.map((genre: GenreResult) => (
          <GenreCard
            key={genre.id}
            id={genre.id}
            name={genre.name}
            image_url={genre.image_url}
          />
        ))}

        <div
          className='col-span-full mt-4 flex h-10 items-center justify-center'
          ref={spinnerRef}
        >
          {isLoading && <SpinnerSVG />}
        </div>
      </div>
    </div>
  );
});

export default GenreSearch;
