import React, {useCallback, useState} from 'react';
import {FlatList, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {UseMutationResult} from 'react-query';
import {
  CardContainer,
  Checkbox,
  Typography,
  Button,
  Spinner,
  Badge,
} from '@components';
import {PostApprovalStatus} from '@modules/group/interfaces';
import {
  PostRequest,
  UpdateMultiplePostsResponse,
} from '@modules/post/interfaces';
import {useTheme} from '@shared/theme';

import EmptyState from './components/EmptyState';
import ConfirmActionBottomModal from './components/ConfirmActionBottomModal';
import PostWithActions from './components/PostWithActions';
import {styles} from './styles';

export interface PostToChangeStatus {
  requestId: number;
  postId: number;
  userId: number;
}

/** Subset used by this UI; compatible with v3 and v5 infinite-query wrappers. */
export interface ManagePendingApprovalPostsQuery {
  data: PostRequest[] | undefined;
  isFetching: boolean;
  getNextPage: () => void;
  totalCount: number;
  isFetchingNextPage: boolean;
}

interface Props {
  postsQuery: ManagePendingApprovalPostsQuery;
  postsMutation: UseMutationResult<
    UpdateMultiplePostsResponse,
    unknown,
    {
      posts: PostToChangeStatus[];
      status: PostApprovalStatus;
    }
  >;
}

const keyExtractor = (p: PostRequest) => p.id?.toString();

const getPostToChangeStatus = (request: PostRequest) => ({
  requestId: request.id,
  postId: request.post.id,
  userId: request.post?.user?.id,
});

export function ManagePendingApprovalPosts({
  postsQuery: {
    data: posts,
    isFetching: isFetchingPosts,
    getNextPage,
    totalCount,
    isFetchingNextPage,
  },
  postsMutation: {mutateAsync: reviewPost, isLoading: isUpdatingPosts},
}: Props) {
  const {theme, iconSizes} = useTheme();
  const {t} = useTranslation();
  const [massiveActionsActive, setMassiveActionsActive] = useState(false);
  const [selectedPosts, setSelectedPosts] = useState<PostToChangeStatus[]>([]);
  const [bottomSheetStatus, setBottomSheetStatus] = useState<
    PostApprovalStatus.APPROVED | PostApprovalStatus.REJECTED | undefined
  >();

  const togglePost = useCallback(
    (postToToggle: PostRequest) => () => {
      setSelectedPosts(prev =>
        prev.some(post => post.requestId === postToToggle.id)
          ? prev.filter(post => post.requestId !== postToToggle.id)
          : [...prev, getPostToChangeStatus(postToToggle)],
      );
    },
    [],
  );

  const renderPostItem = ({item}: {item: PostRequest}) => (
    <View style={styles.postOuterContainer}>
      {massiveActionsActive && (
        <Checkbox
          style={styles.checkbox}
          checked={selectedPosts.some(post => post.requestId === item.id)}
          onPress={togglePost(item)}
        />
      )}
      <PostWithActions
        post={item.post}
        postContent={item.postContent}
        disableActions={massiveActionsActive}
        onApprove={onChangePostStatusPress(PostApprovalStatus.APPROVED, [
          getPostToChangeStatus(item),
        ])}
        onReject={onChangePostStatusPress(PostApprovalStatus.REJECTED, [
          getPostToChangeStatus(item),
        ])}
      />
    </View>
  );

  const onToggleMassiveActionsActive = useCallback(() => {
    if (massiveActionsActive) {
      setSelectedPosts([]);
      setMassiveActionsActive(false);
      return;
    }
    setMassiveActionsActive(true);
    setSelectedPosts(posts?.map(getPostToChangeStatus) ?? []);
  }, [massiveActionsActive, posts]);

  const onChangePostStatusPress =
    (
      status: PostApprovalStatus.APPROVED | PostApprovalStatus.REJECTED,
      postsToSubmit: PostToChangeStatus[],
    ) =>
    () => {
      setSelectedPosts(postsToSubmit);
      setBottomSheetStatus(status);
    };

  const onOpenBottomSheet =
    (status: PostApprovalStatus.APPROVED | PostApprovalStatus.REJECTED) =>
    () => {
      setBottomSheetStatus(status);
    };

  const onCloseBottomSheet = useCallback(() => {
    setBottomSheetStatus(undefined);
    setMassiveActionsActive(false);
    setSelectedPosts([]);
  }, []);

  const onSubmitBottomSheet = useCallback(async () => {
    if (!bottomSheetStatus || !selectedPosts.length) {
      return;
    }

    await reviewPost({
      posts: selectedPosts,
      status: bottomSheetStatus,
    });

    onCloseBottomSheet();
  }, [bottomSheetStatus, onCloseBottomSheet, reviewPost, selectedPosts]);

  return (
    <View
      style={[
        styles.container,
        {backgroundColor: theme.background.elements.grey},
      ]}>
      <View style={styles.innerContainer}>
        <FlatList
          ListEmptyComponent={EmptyState}
          data={posts}
          contentContainerStyle={styles.flatlistContainer}
          showsVerticalScrollIndicator={false}
          keyExtractor={keyExtractor}
          onEndReached={getNextPage}
          renderItem={renderPostItem}
          ListHeaderComponent={
            posts?.length ? (
              <>
                <CardContainer style={styles.pendingPosts}>
                  <Typography weight="semiBold">
                    {t('group.manage_post_approvals.pending_posts')}
                  </Typography>
                  {isFetchingPosts || isFetchingNextPage ? (
                    <Spinner size={iconSizes.x5} />
                  ) : (
                    <Badge
                      variant="primary"
                      value={totalCount}
                      show={!!totalCount}
                    />
                  )}
                </CardContainer>
                <View style={styles.massiveActionsContainer}>
                  <Checkbox
                    checked={massiveActionsActive}
                    onPress={onToggleMassiveActionsActive}
                    title={t('group.manage_post_approvals.massive_actions')}
                  />
                </View>
              </>
            ) : undefined
          }
        />
      </View>
      {massiveActionsActive && (
        <View
          style={[
            styles.massiveActionButtonsContainer,
            {
              backgroundColor: theme.background.elements.default,
              borderTopColor: theme.border.neutral.default,
            },
          ]}>
          <Typography variant="xs" align="center">
            {t('group.manage_post_approvals.posts_selected')}{' '}
            {selectedPosts.length}/{totalCount}
          </Typography>
          <Button
            text={t('group.manage_post_approvals.approve')}
            onPress={onOpenBottomSheet(PostApprovalStatus.APPROVED)}
            size="lg"
            disabled={!selectedPosts.length}
          />
          <Button
            text={t('group.manage_post_approvals.reject')}
            onPress={onOpenBottomSheet(PostApprovalStatus.REJECTED)}
            variant="secondary"
            size="lg"
            disabled={!selectedPosts.length}
          />
        </View>
      )}
      <ConfirmActionBottomModal
        isVisible={!!bottomSheetStatus}
        onClose={onCloseBottomSheet}
        onSubmit={onSubmitBottomSheet}
        status={bottomSheetStatus}
        isLoading={isUpdatingPosts}
        count={selectedPosts?.length}
        isEditionPost={!!posts?.[0]?.postContent?.bodyHtml}
      />
    </View>
  );
}
