import { useQuery } from 'react-query';

import axios from 'axios';

import { getGroupPostDetails } from 'src/services/groups';
import { getById } from 'src/services/posts';

import { type GroupPost } from 'src/types/groups';
import { type Post, type ShareMetadata } from 'src/types/posts';
import { withShareMetadata } from 'src/utils/sharedPost';

import { sharedPostKeys } from './keys';

export type UseSharedPostResult = {
  post: Post | GroupPost | undefined;
  isLoading: boolean;
  notFound: boolean;
  isError: boolean;
};

const isNotFoundError = (error: unknown): boolean =>
  axios.isAxiosError(error) && error.response?.status === 404;

export const useSharedPost = (
  metadata: ShareMetadata | null | undefined,
): UseSharedPostResult => {
  const enabled = !!metadata && withShareMetadata.isShare(metadata);
  const original = enabled ? withShareMetadata.getOriginal(metadata!) : null;

  const isFeed = original?.type === 'feed';
  const queryKey = original
    ? isFeed
      ? sharedPostKeys.feed.detail(original.id)
      : sharedPostKeys.groups.detail(original.groupId, original.id)
    : ['shared-post-disabled'];

  const queryFn = async (): Promise<Post | GroupPost> => {
    if (!original) throw new Error('No original reference');
    const config = { skipNotFoundRedirect: true };
    if (isFeed) {
      const response = await getById(original.id, config);
      return response.data;
    }
    const response = await getGroupPostDetails(
      original.groupId,
      original.id,
      config,
    );
    return response.data;
  };

  const { data, isLoading, isError, error } = useQuery(queryKey, queryFn, {
    enabled,
    retry: (failureCount, err) => {
      if (isNotFoundError(err)) return false;
      return failureCount < 2;
    },
    staleTime: 60_000,
  });

  return {
    post: data,
    isLoading: enabled && isLoading,
    notFound: enabled && isNotFoundError(error),
    isError: enabled && isError && !isNotFoundError(error),
  };
};
