import React, {useState, useCallback, ReactElement} from 'react';
import {ListRenderItemInfo} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useNavigation} from '@react-navigation/native';
import {useMutation, useQueryClient} from '@tanstack/react-query';
import {useDispatch} from 'react-redux';
import {Dialog, List, ListItem, Typography} from '@components';
import {useGoBack} from '@hooks/useGoBack';
import {Attachment} from '@interfaces/attachments';
import {Comment as CommentType} from '@interfaces/comments';
import {useActionMenu} from '@modules/acknowledgement/hooks/useActionMenu';
import {useDeleteAcknowledgement} from '@modules/acknowledgement/hooks/useDeleteAcknowledgement';
import {AckUser, MenuItem} from '@modules/acknowledgement/interfaces';
import {ackQueryKeys} from '@modules/acknowledgement/constants';
import {deleteComment} from '@modules/acknowledgement/services';
import {invalidateAcknowledgement} from '@modules/acknowledgement/utils';
import {setCommentToEdit} from '@redux/comment/comment.actions';
import {Screens} from '@shared/constants';

import styles from './styles';

export enum ContentType {
  ACKNOWLEDGEMENT = 'acknowledgement',
  COMMENT = 'comment',
}

interface CommonProps {
  isVisible: boolean;
  isOwner: boolean;
  onHide: (hide?: boolean) => void;
}

interface AcknowledgementProps extends CommonProps {
  contentType: ContentType.ACKNOWLEDGEMENT;
  acknowledgementId: number;
  body: string;
  attachments: Attachment[];
  acknowledgeds: Nullable<AckUser[]>;
}

interface CommentProps extends CommonProps {
  contentType: ContentType.COMMENT;
  comment: CommentType;
  acknowledgementId?: number;
  isThread?: boolean;
  acknowledgeds?: Nullable<AckUser[]>;
}

type ContentActionsDialogProps = AcknowledgementProps | CommentProps;

const ContentActionsDialog = ({
  isVisible,
  isOwner,
  onHide,
  contentType,
  ...props
}: ContentActionsDialogProps): ReactElement => {
  const navigation = useNavigation();
  const {goBack} = useGoBack();
  const [isDeleteView, setIsDeleteView] = useState(false);
  const {t} = useTranslation();
  const queryClient = useQueryClient();
  const dispatch = useDispatch();

  const acknowledgementId =
    contentType === ContentType.ACKNOWLEDGEMENT
      ? (props as AcknowledgementProps).acknowledgementId
      : (props as CommentProps).acknowledgementId;

  const {mutate: deleteCommentMutate} = useMutation({
    mutationFn: deleteComment,
    onSuccess: () => {
      if (
        contentType === ContentType.COMMENT &&
        !(props as CommentProps).comment?.parentId &&
        (props as CommentProps).isThread
      ) {
        goBack();
      }
      if (acknowledgementId) {
        invalidateAcknowledgement(acknowledgementId);
        queryClient.invalidateQueries({
          queryKey: ackQueryKeys.commentsThread(
            (props as CommentProps).comment.parentId || 0,
          ),
        });
      }
    },
  });

  const {mutate: deleteAcknowledgementMutate} = useDeleteAcknowledgement({
    onSuccess: () => {
      navigation.navigate(Screens.ACKNOWLEDGEMENTS);
    },
  });

  const onEdit = useCallback(() => {
    if (contentType === ContentType.ACKNOWLEDGEMENT) {
      const {
        acknowledgementId: ackId,
        body,
        attachments,
        acknowledgeds,
      } = props as AcknowledgementProps;
      navigation.navigate(Screens.PUBLISH_ACKNOWLEDGEMENT, {
        updateAckId: ackId,
        acknowledgement: {body, attachments},
        acknowledgeds,
      });
    } else {
      const {comment} = props as CommentProps;
      dispatch(setCommentToEdit(comment));
    }
    onHide();
  }, [contentType, onHide, props, navigation, dispatch]);

  const onChangeToDeleteView = () => {
    setIsDeleteView(true);
  };

  const {menuItems, onMenuItemPress, keyExtractor} = useActionMenu({
    isOwner,
    onEdit,
    onDelete: onChangeToDeleteView,
  });

  const onDelete = useCallback(() => {
    if (contentType === ContentType.ACKNOWLEDGEMENT) {
      const {acknowledgementId: ackId} = props as AcknowledgementProps;
      deleteAcknowledgementMutate(ackId);
    } else {
      const {comment} = props as CommentProps;
      deleteCommentMutate(comment.id);
    }

    onHide();
  }, [
    props,
    contentType,
    onHide,
    deleteAcknowledgementMutate,
    deleteCommentMutate,
  ]);

  const onClose = () => {
    setIsDeleteView(false);
    onHide();
  };

  const deleteMessageKey =
    contentType === ContentType.ACKNOWLEDGEMENT
      ? 'acknowledgements.delete_acknowledgement_message'
      : 'acknowledgements.delete_comment_message';

  const renderItem = ({
    item: {key, label, LeftIcon, hide},
  }: ListRenderItemInfo<MenuItem>) =>
    hide ? null : (
      <ListItem
        avatar={{Icon: LeftIcon}}
        title={label}
        style={styles.listItem}
        onItemPress={onMenuItemPress(key)}
      />
    );

  const onGoBack = () => {
    setIsDeleteView(false);
  };

  return (
    <Dialog
      title={isDeleteView ? t('general.delete') : t('general.options')}
      isVisible={isVisible}
      onGoBack={onGoBack}
      withBackButton={isDeleteView}
      onClose={onClose}
      footer={
        isDeleteView
          ? {
              primaryButton: {
                onPress: onDelete,
                text: t('general.delete'),
              },
            }
          : undefined
      }
      contentStyle={styles.dialog}>
      {isDeleteView ? (
        <Typography>{t(deleteMessageKey)}</Typography>
      ) : (
        <List
          keyExtractor={keyExtractor}
          data={menuItems}
          style={styles.list}
          renderItem={renderItem}
        />
      )}
    </Dialog>
  );
};

export default ContentActionsDialog;
