import { useState } from 'react';
import { useQuery } from 'react-query';
import { useNavigate } from 'react-router';

import { useServerPagination } from '@material-hu/hooks/useServerPagination';
import { IconArrowLeft, IconX } from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';

import useSnackbar from '@material-hu/components/design-system/Snackbar';
import Title from '@material-hu/components/design-system/Title';

import { logEvent } from 'src/config/logging';
import { useAuth } from 'src/contexts/JWTContext';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import {
  getFeedPendingApprovalPosts,
  reviewFeedPosts,
} from 'src/services/posts';
import { type FeedPendingPost, OrderBy, PostState } from 'src/types/feed';
import { ApprovalStatus } from 'src/types/groups';
import { PostRequestActionType } from 'src/types/posts';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { type PaginationParams } from 'src/utils/pagination';

import PendingPostsApproval from '../../../components/pendingApprovals/PendingPostsApproval';

import { invalidateGroupPost } from 'src/pages/dashboard/groups/queries';

import {
  feedKeys,
  invalidateFeedPendingApprovalPostList,
  invalidateFeedPostDetail,
  invalidateFeedScheduledPostList,
} from './queries';
import { feedRoutes } from './routes';

const CONFIG_HEADER_HEIGHT = 78;

const FeedPendingPostsApproval = () => {
  const { enqueueSnackbar } = useSnackbar();
  const HugoThemeProvider = useHuGoTheme();
  const navigate = useNavigate();
  const { t } = useTranslation('group');
  const { user } = useAuth();
  const [selectedActionType, setSelectedActionType] =
    useState<PostRequestActionType>(PostRequestActionType.CREATION);

  const serverPagination = useServerPagination({
    labelRowsPerPage: t('ROWS_PER_PAGE'),
    defaultOrderBy: 'CREATED_AT',
    defaultOrder: OrderBy.DESC,
    defaultLimit: 5,
    limitOptions: [5, 10, 20, 50],
  });

  const paginationAndOrder: PaginationParams = {
    ...serverPagination.pagination,
    page: serverPagination.pagination.page + 1,
    order: serverPagination.order,
    orderBy: serverPagination.orderBy,
  };

  // One query per action type so keepPreviousData only applies within a tab (pagination
  // / sort / page size). A single query with keepPreviousData would briefly show the
  // other tab's rows when switching CREATION ↔ EDITION.
  const pendingPostsQueryOptions = {
    select: (r: Awaited<ReturnType<typeof getFeedPendingApprovalPosts>>) =>
      r.data,
    keepPreviousData: true,
    onError: () => {
      enqueueSnackbar({
        title: t('group:pending_approval_posts_loading_error'),
        variant: 'error',
      });
    },
  } as const;

  const creationPendingPostsQuery = useQuery(
    feedKeys.pendingApproval.postList({
      ...paginationAndOrder,
      actionType: PostRequestActionType.CREATION,
    }),
    () =>
      getFeedPendingApprovalPosts(
        paginationAndOrder,
        ApprovalStatus.PENDING,
        PostRequestActionType.CREATION,
      ),
    {
      ...pendingPostsQueryOptions,
      enabled: selectedActionType === PostRequestActionType.CREATION,
    },
  );

  const editionPendingPostsQuery = useQuery(
    feedKeys.pendingApproval.postList({
      ...paginationAndOrder,
      actionType: PostRequestActionType.EDITION,
    }),
    () =>
      getFeedPendingApprovalPosts(
        paginationAndOrder,
        ApprovalStatus.PENDING,
        PostRequestActionType.EDITION,
      ),
    {
      ...pendingPostsQueryOptions,
      enabled: selectedActionType === PostRequestActionType.EDITION,
    },
  );

  const pendingPostsQuery =
    selectedActionType === PostRequestActionType.CREATION
      ? creationPendingPostsQuery
      : editionPendingPostsQuery;

  const invalidatePendingPosts = () => {
    invalidateFeedPendingApprovalPostList();
  };

  return (
    <HugoThemeProvider>
      <Stack
        sx={{
          width: '100%',
          alignItems: 'center',
          minHeight: '100%',
        }}
      >
        <Stack
          sx={{
            width: '100%',
            alignItems: 'center',
            justifyContent: 'space-between',
            flexDirection: 'row',
            backgroundColor: theme =>
              theme.palette.new.background.layout.tertiary,
            gap: 1,
            py: 1.5,
            px: 3,
            height: `${CONFIG_HEADER_HEIGHT}px`,
          }}
        >
          <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}>
            <IconButton onClick={() => navigate(-1)}>
              <IconArrowLeft />
            </IconButton>
            <Title
              title={t('group:configuration')}
              variant="L"
            />
          </Stack>
          <IconButton onClick={() => navigate(feedRoutes.feed())}>
            <IconX />
          </IconButton>
        </Stack>
        <Stack
          sx={{
            width: '100%',
            px: 3,
            pt: 2,
            flex: 1,
            backgroundColor: theme =>
              theme.palette.new.background.layout.default,
          }}
        >
          <PendingPostsApproval
            pendingPostsQuery={pendingPostsQuery}
            reviewPostsService={({ approvalStatus, postIds }) =>
              reviewFeedPosts(approvalStatus, postIds)
            }
            selectedActionType={selectedActionType}
            onActionTypeChange={setSelectedActionType}
            onReviewSuccess={(variables, pendingPosts) => {
              const list = pendingPosts as FeedPendingPost[];
              const acceptedUserIds = variables.postIds.map(
                postId =>
                  list.find(pendingPost => pendingPost.id === postId)?.post.user
                    .id,
              );
              logEvent(`FEED_POST_${variables.approvalStatus}`, {
                resolutionUserId: user?.id,
                acceptedUserIds,
                postIds: variables.postIds,
              });
              invalidatePendingPosts();
              if (
                variables.approvalStatus === ApprovalStatus.APPROVED &&
                selectedActionType === PostRequestActionType.EDITION
              ) {
                variables.postIds.forEach(requestId => {
                  const pp = list.find(p => p.id === requestId);
                  if (!pp || pp.actionType !== PostRequestActionType.EDITION) {
                    return;
                  }
                  const livePost = pp.post;
                  invalidateFeedPostDetail(livePost.id);
                  if (livePost.group?.id) {
                    invalidateGroupPost(String(livePost.group.id), livePost.id);
                  }
                });
              }
              if (
                list.some(
                  pendingPost => pendingPost.post.state === PostState.SCHEDULED,
                )
              )
                invalidateFeedScheduledPostList();
            }}
            serverPagination={serverPagination}
          />
        </Stack>
      </Stack>
    </HugoThemeProvider>
  );
};

export default FeedPendingPostsApproval;
