import { getGifs, IGif, IPaginatedResponse } from '@livelike/javascript';
import { useCallback, useRef, useState } from 'react';

export type GifPickerState = {
  gifImages: IGif[];
  isLoading: boolean;
  error: null;
};

const DEFAULT_GIF_STATE: GifPickerState = {
  gifImages: [],
  isLoading: false,
  error: null,
};

export function useGifPicker() {
  const [{ gifImages, isLoading, error }, setGifState] =
    useState(DEFAULT_GIF_STATE);
  let _loadNextGifImages: IPaginatedResponse<IGif>['next'];
  const timeoutRef = useRef(null);

  const onGifSearchInputChange = useCallback(
    (gifSearchInput, { debounce } = { debounce: true }) => {
      const searchGif = () => {
        setGifState({
          gifImages: [],
          isLoading: true,
          error: null,
        });
        getGifs({
          search: gifSearchInput,
        })
          .then((res) => {
            res.results = res.results.filter(
              (value, index, self) =>
                index === self.findIndex((gif) => gif.id === value.id)
            );
            return res;
          })
          .then((res) => {
            setGifState({
              gifImages: res.results,
              isLoading: false,
              error: null,
            });
            _loadNextGifImages = res.next;
          })
          .catch((error) => {
            setGifState({
              gifImages: [],
              isLoading: false,
              error: error.message ?? 'Error fetching gif images',
            });
          });
      };

      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
      timeoutRef.current = setTimeout(searchGif, !debounce ? 0 : 250);
    },
    [gifImages, isLoading, error]
  );

  const loadNextGifImages = () => {
    return _loadNextGifImages().then((res) => {
      setGifState({
        gifImages: [...gifImages, ...res.value],
        isLoading: false,
        error: null,
      });
    });
  };

  return {
    isLoading,
    gifImages,
    loadNextGifImages,
    onGifSearchInputChange,
    error,
  };
}
