import { FC, useMemo } from 'react';

import { useInfiniteQuery, useQuery } from 'react-query';
import { useNavigate } from 'react-router-dom';

import Box from '@material-hu/mui/Box';

import HuSpinner from '@material-hu/components/design-system/ProgressIndicators/Spinner';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import useGeneralError from 'src/hooks/useGeneralError';
import useRequiredParams from 'src/hooks/useRequiredParams';
import {
  addGroupFeedListDataReaction,
  removeGroupFeedListDataReaction,
  groupsKeys,
} from 'src/pages/dashboard/groups/queries';
import { groupsRoutes } from 'src/pages/dashboard/groups/routes';
import { getGroupDetails, getGroupPosts } from 'src/services/groups';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';

import PinnedPostsLayout from 'src/components/pinnedPosts/PinnedPostsLayout';

import GroupPostCard from './components/GroupPostCard';
import { GroupMemberProvider } from './GroupMemberContext';

const GroupPinnedPosts: FC = () => {
  const navigate = useNavigate();
  const { id: groupId } = useRequiredParams(['id']);
  const { t } = useTranslation(['post', 'general']);
  const { enqueueSnackbar } = useSnackbar();
  const showGeneralError = useGeneralError();

  const { data: groupData, isLoading: isLoadingGroup } = useQuery(
    groupsKeys.detail(groupId),
    () => getGroupDetails(groupId),
    {
      onError: err => {
        showGeneralError(err, t('error_loading_group'));
      },
    },
  );

  const {
    data: pinPostsData,
    isLoading: isLoadingPosts,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery(
    groupsKeys.postPinList(groupId),
    ({ pageParam = '' }) => getGroupPosts(groupId, pageParam, undefined, true),
    {
      getNextPageParam: lastPage => lastPage?.data?.cursor,
      onError: err => {
        enqueueSnackbar({
          title: t('error_loading_posts') + err,
          variant: 'error',
        });
      },
    },
  );

  const group = groupData?.data;

  const pinPosts = useMemo(
    () => pinPostsData?.pages?.flatMap(page => page?.data?.items || []) || [],
    [pinPostsData],
  );

  const handleBack = () => {
    navigate(groupsRoutes.detail(groupId));
  };

  const handleClose = () => {
    navigate(groupsRoutes.detail(groupId));
  };

  const handleAddReaction = (postId: number, emoji: string, unified: string) =>
    addGroupFeedListDataReaction(postId, groupId, emoji, unified);

  const handleRemoveReaction = (postId: number, emoji: string) =>
    removeGroupFeedListDataReaction(postId, groupId, emoji);

  if (isLoadingGroup) {
    return (
      <PinnedPostsLayout
        onBack={handleBack}
        onClose={handleClose}
        isLoading={true}
        isEmpty={false}
      >
        <Box
          sx={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            py: 4,
          }}
        >
          <HuSpinner />
        </Box>
      </PinnedPostsLayout>
    );
  }

  if (!group) {
    return null;
  }

  return (
    <GroupMemberProvider
      members={group.members}
      publicationPolicy={group.publicationPolicy}
      privacyPolicy={group.privacyPolicy}
      approvalPolicy={group.approvalPolicy}
      isArchived={group.isArchived}
    >
      <PinnedPostsLayout
        onBack={handleBack}
        onClose={handleClose}
        isLoading={isLoadingPosts}
        isEmpty={pinPosts.length === 0}
        hasNextPage={hasNextPage}
        isFetchingNextPage={isFetchingNextPage}
        fetchNextPage={fetchNextPage}
      >
        {pinPosts.map(post => (
          <Box
            key={post.id}
            sx={{ mt: 2 }}
            data-post-id={post.id}
          >
            <GroupPostCard
              isPinned
              hidePinIcon
              onAddReaction={handleAddReaction}
              onRemoveReaction={handleRemoveReaction}
              post={post}
            />
          </Box>
        ))}
      </PinnedPostsLayout>
    </GroupMemberProvider>
  );
};

export default GroupPinnedPosts;
