'use client';

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

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

export type SearchResult = components['schemas']['BaseSearchResult'];

interface PersonaResult {
  id: string;
  name: string;
  image_s3_id: string;
  root_clip_id: string;
  user_display_name: string;
  user_handle: string;
  user_image_url: string;
  description?: string;
  is_public?: boolean;
  is_trashed?: boolean;
}

const PersonaSearch = observer(() => {
  const { search, session } = useStores();
  const [searching, setSearching] = useState(false);

  const isPersonaSearchEnabled = session.flags?.['persona-search'];

  useEffect(() => {
    if (!isPersonaSearchEnabled) return;

    const searchPersonas = async () => {
      setSearching(true);
      await search.searchData(
        search.searchTerm,
        false,
        'public_persona',
        search.searchRankingType
      );
      setSearching(false);
    };

    if (search.searchTerm) {
      searchPersonas();
    }
  }, [search.searchTerm, search.searchRankingType, isPersonaSearchEnabled]);

  const { ref: spinnerRef } = useInView({
    threshold: 0,
    onChange: async (inView) => {
      if (inView && !searching && isPersonaSearchEnabled) {
        setSearching(true);
        await search.searchData(
          search.searchTerm,
          true,
          'public_persona',
          search.searchRankingType
        );
        setSearching(false);
      }
    },
  });

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

  const searchResults = (searchResult?.result || []).map((result: any) => {
    return {
      id: result.id,
      name: result.name,
      image_s3_id: result.image_s3_id,
      root_clip_id: result.root_clip_id,
      user_display_name: result.user_display_name,
      user_handle: result.user_handle,
      user_image_url: result.user_image_url,
      description: result.description,
      is_public: result.is_public,
      is_trashed: result.is_trashed,
    };
  });

  if (!isPersonaSearchEnabled) return null;

  return (
    <div
      className='sticky mr-5 ml-6 flex flex-col overflow-y-auto'
      style={{ scrollbarWidth: 'none' }}
    >
      <div className='h-32 pb-2'>
        {searching ? (
          <div className='flex flex-row items-center'>
            <span className='font-sans text-xl font-bold'>
              {`Searching ${
                search.searchTerm.length > 0
                  ? ` "${search.searchTerm}"`
                  : 'popular personas'
              }...`}
            </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}"`
              : ''}
          </span>
        ) : (
          <span className='font-sans text-xl font-bold'>
            {'No personas found.'}
          </span>
        )}
      </div>
      <motion.div className='flex flex-1 flex-col overflow-y-auto'>
        <div className='grid grid-cols-2 gap-6 md:grid-cols-3 lg:grid-cols-4'>
          {searchResults.map((persona: PersonaResult) => (
            <PersonaCard
              key={persona.id}
              id={persona.id}
              name={persona.name}
              image_url={persona.image_s3_id}
              user_image_url={persona.user_image_url}
              user_display_name={persona.user_display_name}
              user_handle={persona.user_handle}
              root_clip_id={persona.root_clip_id}
            />
          ))}
          <div ref={spinnerRef} />
        </div>
      </motion.div>
    </div>
  );
});

export default PersonaSearch;
