import React, {useCallback, useEffect, useState} from 'react';
import {ListRenderItem, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {FlatList} from 'react-native-gesture-handler';
import {
  IconClock,
  IconCopy,
  IconEdit,
  IconSend,
  IconTrash,
} from '@tabler/icons-react-native';
import {useMutation} from 'react-query';
import {BasePost, Post} from '@components/_custom';
import {Dialog, ListFooter, ListRow} from '@components/_HuGo';
import {Typography, RefreshControl} from '@components/_core';
import {useGetScheduledPosts} from '@hooks/useGetScheduledPosts';
import {useGoBack} from '@hooks/useGoBack';
import {useSafeAreaBottomPadding} from '@hooks/useSafeAreaBottomPadding';
import {Navigation} from '@interfaces/navigation';
import {Post as PostType} from '@modules/post/interfaces';
import {deletePost, publishScheduledPost} from '@modules/post/services';
import {deleteGroupPost} from '@modules/group/services';
import {showSnackbar} from '@redux/dispatchers';
import {DEFAULT_THRESHOLD, Screens} from '@shared/constants';
import {useTheme} from '@shared/theme';
import {HUMAND_URL} from '@shared/keys';
import {copyToClipboard, getFullDateTime} from '@shared/utils';

import ListEmptyComponent from './components/ListEmptyComponent';
import {styles} from './styles';

const keyExtractor = (item: PostType) => `${item.id}`;

function PostsScheduled({
  navigation,
  route: {params},
}: Navigation<Screens.POSTS_SCHEDULED>) {
  const groupId = params?.groupId;
  const {t} = useTranslation();
  const {theme} = useTheme();
  const {goBack} = useGoBack();
  const [showOptionsDialogForPost, setShowOptionsDialogForPost] =
    useState<Nullable<PostType>>(null);
  const [isDeleteVisible, setIsDeleteVisible] = useState(false);
  const paddingBottom = useSafeAreaBottomPadding({bottom: 10});

  const {
    data: scheduledPosts = [],
    isFetchingNextPage,
    isRefreshing,
    refresh,
    getNextPage,
    deleteScheduledPostFromCache,
  } = useGetScheduledPosts(groupId);

  useEffect(() => {
    !scheduledPosts.length && goBack();
  }, [goBack, scheduledPosts]);

  const renderItem: ListRenderItem<PostType> = ({item}) => (
    <ListRow style={styles.listRowContainer}>
      <ListRow.CardContainer style={styles.cardContainer}>
        <Post
          style={styles.postContainer}
          post={item as BasePost}
          withOptions
          onPressOptions={onPressOptions(item)}
        />
        <View style={styles.dateContainer}>
          <Typography variant="xs">
            {t('post.will_be_published_on', {
              date: getFullDateTime(item.publicationDatetime),
            })}
          </Typography>
        </View>
      </ListRow.CardContainer>
    </ListRow>
  );

  const onEndReached = useCallback(() => {
    if (!isFetchingNextPage) {
      getNextPage();
    }
  }, [getNextPage, isFetchingNextPage]);

  // Show options dialog
  const onPressOptions = (item: PostType) => () =>
    setShowOptionsDialogForPost(item);
  const onHide = () => setShowOptionsDialogForPost(null);

  // Publish scheduled post
  const deletePostMutation = useMutation({
    mutationFn: deletePost,
    onSuccess: (_, {id}) => {
      onSuccessDelete(id);
    },
  });

  // Delete post
  const publishScheduledPostMutation = useMutation({
    mutationFn: publishScheduledPost,
    onSuccess: () => {
      if (showOptionsDialogForPost) {
        deleteScheduledPostFromCache({
          postId: showOptionsDialogForPost.id,
        });
      }
      onHide();
      showSnackbar({
        title: t('post.successful_publication'),
        variant: 'success',
      });
    },
  });

  // Edit post
  const onEditPost = () => {
    onHide();
    // Timeout to wait close modal
    setTimeout(() => {
      if (showOptionsDialogForPost?.groupId) {
        navigation.navigate(Screens.PUBLISH_GROUP_POST, {
          groupId: showOptionsDialogForPost.groupId,
          post: showOptionsDialogForPost as PostType,
        });
      } else {
        navigation.navigate(Screens.PUBLISH_POST, {
          post: showOptionsDialogForPost as PostType,
          isScheduled: true,
        });
      }
    }, 250);
  };

  const onCopyLink = () => {
    if (!showOptionsDialogForPost) return;
    const {id, groupId: postGroupId} = showOptionsDialogForPost;
    const link = postGroupId
      ? `${HUMAND_URL}groups/${postGroupId}/post/${id}`
      : `${HUMAND_URL}feed/${id}`;
    onHide();
    copyToClipboard(
      {text: link},
      {variant: 'success', title: t('deeplinks.copied')},
    );
  };

  // Reschedule post
  const onRescheduleItem = () => {
    if (showOptionsDialogForPost) {
      navigation.navigate(Screens.RESCHEDULE_POST, {
        postId: showOptionsDialogForPost.id,
        groupId: showOptionsDialogForPost.groupId,
        scheduleDateTime: new Date(
          showOptionsDialogForPost.publicationDatetime,
        ),
        sendNotification: showOptionsDialogForPost.sendNotification,
      });
      onHide();
    }
  };

  const onPublishItem = () => {
    if (showOptionsDialogForPost) {
      publishScheduledPostMutation.mutate(showOptionsDialogForPost.id);
    }
  };

  // Delete Logic
  const onDeleteItem = () => setIsDeleteVisible(true);
  const closeDeletePostDialog = () => setIsDeleteVisible(false);
  const handleDelete = () => {
    if (showOptionsDialogForPost) {
      if (groupId) {
        deleteGroupPostMutation.mutate({
          groupId,
          postId: showOptionsDialogForPost.id,
          isScheduled: true,
        });
      } else {
        deletePostMutation.mutate({
          id: showOptionsDialogForPost.id,
          isScheduled: true,
        });
      }
    }
  };
  const onSuccessDelete = (postId?: number) => {
    showSnackbar({
      title: t('group.post_deleted'),
      variant: 'success',
    });
    if (postId) {
      deleteScheduledPostFromCache({
        postId,
      });
    }
    closeDeletePostDialog();
    // Timeout to wait to close prev modal
    setTimeout(onHide, 500);
  };
  const deleteGroupPostMutation = useMutation({
    mutationFn: deleteGroupPost,
    onSuccess: (_, {postId}) => {
      onSuccessDelete(postId);
    },
  });

  return (
    <View
      style={[
        styles.container,
        {
          paddingBottom,
          backgroundColor: theme.background.layout.default,
        },
      ]}>
      <FlatList
        showsVerticalScrollIndicator={false}
        data={scheduledPosts}
        keyExtractor={keyExtractor}
        refreshControl={
          <RefreshControl refreshing={isRefreshing} onRefresh={refresh} />
        }
        ListEmptyComponent={ListEmptyComponent}
        ListFooterComponent={<ListFooter isVisible={isFetchingNextPage} />}
        contentContainerStyle={[
          styles.contentContainer,
          {backgroundColor: theme.background.layout.default},
        ]}
        renderItem={renderItem}
        onEndReached={onEndReached}
        onEndReachedThreshold={DEFAULT_THRESHOLD}
      />
      <Dialog
        title={t('post.more_options')}
        onClose={onHide}
        isVisible={!!showOptionsDialogForPost}>
        <View style={styles.dialogContent}>
          <ListRow onPress={onCopyLink}>
            <ListRow.Avatar Icon={IconCopy} />
            <Typography align="left" weight="semiBold">
              {t('deeplinks.copy_link')}
            </Typography>
          </ListRow>
          <ListRow onPress={onEditPost}>
            <ListRow.Avatar Icon={IconEdit} />
            <Typography align="left" weight="semiBold">
              {t('post.edit')}
            </Typography>
          </ListRow>
          <ListRow onPress={onRescheduleItem}>
            <ListRow.Avatar Icon={IconClock} />
            <Typography align="left" weight="semiBold">
              {t('post.reschedule')}
            </Typography>
          </ListRow>
          {!groupId && (
            <ListRow
              onPress={onPublishItem}
              disabled={publishScheduledPostMutation.isLoading}>
              <ListRow.Avatar
                isLoading={publishScheduledPostMutation.isLoading}
                Icon={IconSend}
              />
              <Typography align="left" weight="semiBold">
                {t('post.send_now')}
              </Typography>
            </ListRow>
          )}
          <ListRow onPress={onDeleteItem}>
            <ListRow.Avatar Icon={IconTrash} />
            <Typography align="left" weight="semiBold">
              {t('post.delete')}
            </Typography>
          </ListRow>
        </View>
      </Dialog>
      <Dialog
        title={t('general.confirmation')}
        onClose={closeDeletePostDialog}
        isVisible={isDeleteVisible}
        footer={{
          primaryButton: {
            text: t('post.delete'),
            onPress: handleDelete,
            isLoading: deleteGroupPostMutation.isLoading,
          },
          secondaryButton: {
            text: t('general.cancel'),
            onPress: closeDeletePostDialog,
          },
        }}>
        <Typography>{t('post.confirm_delete_post')}</Typography>
      </Dialog>
    </View>
  );
}

export default PostsScheduled;
