import { type FC, memo, useMemo } from 'react';
import { useInfiniteQuery } from 'react-query';
import { useNavigate } from 'react-router-dom';

import { IconBan, IconListSearch } from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuAvatar from '@material-hu/components/design-system/Avatar';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { useAuth } from 'src/contexts/JWTContext';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import useRequiredParams from 'src/hooks/useRequiredParams';
import usePostsViewTracking from 'src/pages/dashboard/feed/hooks/usePostsViewTracking';
import { getGroupPosts } from 'src/services/groups';
import { type GroupPost } from 'src/types/groups';
import { getLastPinnedPost } from 'src/utils/feed';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { withShareMetadata } from 'src/utils/sharedPost';

import InfiniteList from 'src/components/list/InfiniteList';
import PinnedPostPreview from 'src/components/post/PinnedPostPreview';

import { FeedPostSkeleton } from '../../events/components/skeleton/FeedPostSkeleton';
import { useGroupMember } from '../GroupMemberContext';
import {
  addGroupFeedListDataReaction,
  groupsKeys,
  removeGroupFeedListDataReaction,
} from '../queries';
import { groupsRoutes } from '../routes';

import GroupPostCard from './GroupPostCard';

const GroupPostList: FC = () => {
  const { enqueueSnackbar } = useSnackbar();
  const { t } = useTranslation(['post', 'group']);
  const { id: groupId } = useRequiredParams(['id']);
  const navigate = useNavigate();
  const { user, instance } = useAuth();
  const { userCanSeePosts, isClosedGroup, userIsMember } = useGroupMember();
  const HugoThemeProvider = useHuGoTheme();
  const { data: pinnedData } = 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',
        });
      },
      enabled: userCanSeePosts,
    },
  );

  const {
    data,
    isLoading,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isFetching,
  } = useInfiniteQuery(
    groupsKeys.postList(groupId),
    ({ pageParam = '' }) => getGroupPosts(groupId, pageParam),
    {
      getNextPageParam: lastPage => lastPage?.data?.cursor,
      onError: err => {
        enqueueSnackbar({
          title: t('error_loading_posts') + err,
          variant: 'error',
        });
      },
      enabled: userCanSeePosts,
    },
  );

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

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

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

  const pinnedPostsCount = pinnedPosts.length;
  const lastPinnedPost = useMemo(
    () => getLastPinnedPost<GroupPost>(pinnedPosts),
    [pinnedPosts],
  );

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

  // Filter out ALL pinned posts from regular feed
  const unpinnedPosts = useMemo(() => {
    const pinnedPostIds = new Set(pinnedPosts.map(p => p.id));
    return posts.filter(post => !pinnedPostIds.has(post.id));
  }, [posts, pinnedPosts]);

  const handleViewAllPinnedPosts = () => {
    navigate(groupsRoutes.pinnedPosts(groupId!));
  };

  const postsForViewTracking = useMemo(
    () =>
      [...pinnedPosts, ...posts]
        .filter(
          post =>
            !post.viewed && // Not already viewed
            post.user.id !== user?.id && // Not owner's post
            userIsMember, // User is a member of the group
        )
        .map(post => withShareMetadata.toViewTrackingPost(post)),
    [pinnedPosts, posts, user?.id, userIsMember],
  );

  // Track post views
  usePostsViewTracking({
    posts: postsForViewTracking,
    userId: user?.id,
    instanceId: instance?.id,
    context: 'groups',
  });

  if (isClosedGroup && !userCanSeePosts) {
    return (
      <Stack
        sx={{
          flexDirection: 'row',
          p: 2,
          gap: 1.5,
          borderRadius: '20px',
          backgroundColor: 'white',
        }}
      >
        <Stack
          sx={{
            color: 'secondary.main',
            display: 'flex',
            justifyContent: 'center',
          }}
        >
          <IconBan />
        </Stack>
        <Stack sx={{ gap: 1 }}>
          <Typography variant="subtitle1">{t(`group:closed_group`)}</Typography>
          <Typography variant="caption">
            {t('group:close_group_info')}
          </Typography>
        </Stack>
      </Stack>
    );
  }

  return (
    <InfiniteList
      isSuccess={!!data}
      isLoading={isLoading || isFetching}
      loadingSkeleton={isLoading}
      fetchNextPage={fetchNextPage}
      hasNextPage={hasNextPage}
      isFetchingNextPage={isFetchingNextPage}
      isEmpty={
        !data?.pages?.[0]?.data?.items?.length &&
        !pinnedData?.pages?.[0]?.data?.items?.length &&
        !lastPinnedPost
      }
      noResultsLabel={
        <HuCardContainer
          fullWidth
          sx={{ p: 1 }}
        >
          <Stack sx={{ alignItems: 'center' }}>
            <HuAvatar Icon={IconListSearch} />
            <Typography
              variant="globalM"
              fontWeight="fontWeightSemiBold"
            >
              {t(`group:empty_post_list`)}
            </Typography>
          </Stack>
        </HuCardContainer>
      }
      renderSkeleton={
        <HugoThemeProvider>
          <Stack
            sx={{
              gap: 2,
              '.MuiPaper-root': {
                borderColor: theme => theme.palette.new.border.neutral.default,
              },
            }}
          >
            {Array.from({ length: 3 }, (_, i) => (
              <FeedPostSkeleton key={`skeleton-${i}`} />
            ))}
          </Stack>
        </HugoThemeProvider>
      }
    >
      {lastPinnedPost && (
        <PinnedPostPreview
          postId={lastPinnedPost.id}
          pinnedPostsCount={pinnedPostsCount}
          onViewAllPinnedPosts={handleViewAllPinnedPosts}
        >
          <GroupPostCard
            post={lastPinnedPost}
            isPinned
            hidePinIcon
            hideTranslation
            onAddReaction={handleAddReaction}
            onRemoveReaction={handleRemoveReaction}
          />
        </PinnedPostPreview>
      )}
      {unpinnedPosts?.map(post => (
        <Box
          key={`post-${post.id}`}
          sx={{ mb: 2 }}
          data-post-id={post.id}
        >
          <GroupPostCard
            isPinned={false}
            onAddReaction={handleAddReaction}
            onRemoveReaction={handleRemoveReaction}
            post={post}
          />
        </Box>
      ))}
    </InfiniteList>
  );
};

export default memo(GroupPostList);
