import {
  useInfiniteQuery,
  UseInfiniteQueryResult,
  UseQueryResult,
  useQuery,
} from 'react-query';

import { AxiosResponse } from 'axios';

import useGeneralError from 'src/hooks/useGeneralError';
import { feedKeys } from 'src/pages/dashboard/feed/queries';
import { getById, getList } from 'src/services/posts';
import { Post } from 'src/types/posts';
import { CursorPagination } from 'src/types/services';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';

const normalizePinnedPostsResponse = (
  response: AxiosResponse<CursorPagination<Post[]>>,
): AxiosResponse<CursorPagination<Post[]>> => {
  const responseData = response.data as CursorPagination<Post[]> | Post[];

  if (Array.isArray(responseData)) {
    return {
      ...response,
      data: {
        items: responseData,
        cursor: '',
      },
    };
  }

  return {
    ...response,
    data: {
      items: Array.isArray(responseData.items) ? responseData.items : [],
      cursor: responseData.cursor ?? null,
    },
  };
};

export const useFeed = (): {
  feedDetail: (id: string) => UseQueryResult<AxiosResponse<Post>>;
  pinnedPosts: () => UseInfiniteQueryResult<
    AxiosResponse<CursorPagination<Post[]>>
  >;
} => {
  const showGeneralError = useGeneralError();

  const { t } = useTranslation('post');

  const feedDetail = (id: string) =>
    useQuery(feedKeys.detail(id), () => getById(id), {
      onError: err => {
        showGeneralError(err, t('post:error_loading_post_detail'));
      },
      staleTime: 120000,
    });

  const pinnedPosts = () =>
    useInfiniteQuery(
      feedKeys.pinned(),
      ({ pageParam = '' }) =>
        getList(pageParam, false, '', 20, true).then(
          normalizePinnedPostsResponse,
        ),
      {
        getNextPageParam: lastPage => lastPage?.data?.cursor || undefined,
        onError: err => {
          showGeneralError(err, t('post:error_loading_posts'));
        },
        staleTime: 120000,
      },
    );

  return {
    feedDetail,
    pinnedPosts,
  };
};

export default useFeed;
