import {useCallback, useEffect, useMemo, useState} from 'react';
import {useQuery} from '@hooks/queries-v5/useQuery';
import {useDebounce} from '@hooks/useDebounce';
import {LinkPreview, LinkPreviewsBodyParam} from '@interfaces/linkPreview';
import {postQueryKeys} from '@modules/post/constants';
import {getLinkPreview} from '@services/linkPreview';

import {getTextUrls} from '../utils';

const NO_PREVIEW_INDEX = -1;

interface Params {
  text: string;
  language: string;
  setLinkPreviews: (val: LinkPreviewsBodyParam) => void;
}

export const useLinks = ({text, language, setLinkPreviews}: Params) => {
  const debouncedText = useDebounce(text);
  const [indexToPreview, setIndexToPreview] = useState(0);

  const urls = useMemo(() => getTextUrls(debouncedText), [debouncedText]);

  useEffect(() => {
    setIndexToPreview(0);
  }, [debouncedText]);

  const hasLinkPreview = indexToPreview >= 0 && urls.length > 0;
  const currentUrl = hasLinkPreview ? urls[indexToPreview] : null;

  const linkPreviewQuery = useQuery(
    postQueryKeys.linkPreview(currentUrl, language),
    () =>
      currentUrl ? getLinkPreview(currentUrl, language) : Promise.resolve(null),
    {enabled: Boolean(currentUrl)},
  );

  const previewAtIndex =
    hasLinkPreview && linkPreviewQuery.data
      ? (linkPreviewQuery.data as LinkPreview)
      : undefined;

  const onPreviewClose = useCallback(() => {
    setIndexToPreview(
      urls.length > indexToPreview + 1 ? indexToPreview + 1 : NO_PREVIEW_INDEX,
    );
  }, [indexToPreview, urls.length]);

  useEffect(() => {
    if (
      !hasLinkPreview ||
      !currentUrl ||
      linkPreviewQuery.isPending ||
      !linkPreviewQuery.data
    ) {
      setLinkPreviews(null);
      return;
    }
    setLinkPreviews({[currentUrl]: linkPreviewQuery.data as LinkPreview});
  }, [
    currentUrl,
    hasLinkPreview,
    linkPreviewQuery.data,
    linkPreviewQuery.isPending,
    setLinkPreviews,
  ]);

  const isAwaitingPreview =
    hasLinkPreview &&
    linkPreviewQuery.data === undefined &&
    linkPreviewQuery.isLoading;

  return {
    hasLinkPreview,
    currentUrl,
    previewAtIndex,
    isAwaitingPreview,
    onPreviewClose,
  };
};
