import { useCallback, useEffect, useRef, useState } from 'react';

import type { LookupTrackItem } from '@theorchard/songwhip-api';

import Box from '~/src/components/Box';
import FadeOnMount from '~/src/components/FadeOnMount';
import SearchTextInput from '~/src/components/SearchTextInput';
import { useI18n } from '~/src/lib/i18n';
import { useAppRouter } from '~/src/lib/router2';
import { getArtistTracksApi } from '~/src/lib/songwhipApi/users/getArtistTracksApi';
import { useTracker } from '~/src/lib/tracker/useTracker';
import onceIdle from '~/src/lib/utils/onceIdle';
import { TrackSearchResults } from './TrackSearchResults';
import { TrackSuggestions } from './TrackSuggestions';

export const TrackSearch = ({
  artistUrl,
  onSelectTrack,
}: {
  artistUrl: string;
  onSelectTrack: (track: LookupTrackItem) => void;
}) => {
  const searchRef = useRef<HTMLInputElement>(null);

  const { t } = useI18n('create');
  const { trackEvent } = useTracker();
  const router = useAppRouter();
  const searchQuery = router.getAsQuery().q;

  const [suggestedTracks, setSuggestedTracks] = useState<LookupTrackItem[]>();
  const [tracks, setTracks] = useState<LookupTrackItem[]>();

  const [isSuggestionsLoading, setIsSuggestionsLoading] = useState(false);
  const [isTracksLoading, setIsTracksLoading] = useState(false);

  const isLoading = isSuggestionsLoading || isTracksLoading;

  useEffect(() => {
    // load suggestions only once, only when search query is empty
    if (searchQuery || suggestedTracks !== undefined) return;

    setIsSuggestionsLoading(true);

    getArtistTracksApi({
      artistUrl,
      limit: 10,
    })
      .then(({ items }) => {
        setSuggestedTracks(items);
      })
      .finally(() => {
        setIsSuggestionsLoading(false);

        // make sure loading is false before focusing
        onceIdle(() => {
          searchRef.current?.focus();
        });
      });
  }, [searchQuery]);

  useEffect(() => {
    if (searchQuery) {
      setIsTracksLoading(true);

      getArtistTracksApi({
        artistUrl,
        term: searchQuery,
      })
        .then(({ items }) => {
          setTracks(items);
        })
        .finally(() => {
          setIsTracksLoading(false);

          // make sure loading is false before focusing
          onceIdle(() => {
            searchRef.current?.focus();
          });
        });
    } else {
      // reset tracks to avoid showing old results
      // and flickering on switching between search and suggestions
      setTracks(undefined);
    }
  }, [searchQuery]);

  return (
    <FadeOnMount>
      <Box maxWidth="48rem" width="100%">
        <SearchTextInput
          inputRef={searchRef}
          isLoading={isLoading}
          isDisabled={isLoading}
          testId="searchInput"
          height="5rem"
          placeholder={
            isSuggestionsLoading
              ? t('track.fetchingSuggestions')
              : t('track.searchPlaceholder')
          }
          defaultValue={searchQuery}
          onInputEnd={useCallback(({ value }) => {
            router.setQuery({
              q: value || undefined,
            });

            trackEvent({
              type: 'search',
              id: 'create-track-page:lookup-artist-tracks',
              term: value,
            });
          }, [])}
          autoFocus
          centerText
        />
        <Box margin="3rem 0 0">
          {searchQuery ? (
            <TrackSearchResults tracks={tracks} onTrackSelect={onSelectTrack} />
          ) : (
            <TrackSuggestions
              tracks={suggestedTracks}
              onSelectTrack={onSelectTrack}
            />
          )}
        </Box>
      </Box>
    </FadeOnMount>
  );
};
