import { useMutation, useQueryClient } from 'react-query';
import { useMatch } from 'react-router';

import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import { clearTicketDetailUnreadMessages } from 'src/pages/dashboard/tickets/queries';
import { ChatType, Message, MessageStatus } from 'src/types/chats';
import { FormType } from 'src/types/forms';
import { createMessage, Values, addMessageUser } from 'src/utils/chats';
import { useTranslation } from 'src/components/dashboard/chat/i18n';

import {
  chatKeys,
  pushChatDetailMessage,
  replaceChatDetailMessage,
  clearDetailUnreadMessages,
} from 'src/components/dashboard/chat/queries';
import {
  formKeys,
  pushFormDetailMessage,
  replaceFormDetailMessage,
  clearFormDetailUnreadMessages,
} from 'src/components/dashboard/form/queries';
import { formSkeletonRoutes } from 'src/components/dashboard/form/routes';

const useSendChatMessage = (
  id: number,
  chatType: ChatType,
  sendMessageWrap: Function,
  onMutateSendMessage: Function,
  onSuccessSendMessage: Function,
  messageToReply?: Message,
) => {
  const queryClient = useQueryClient();
  const matchFormChat = useMatch(formSkeletonRoutes.form.chat(FormType.FORM));
  const { t } = useTranslation();
  const { user } = useAuth();
  const showGeneralError = useGeneralError();

  const { mutate: sendMessageMutate, isLoading } = useMutation(
    (values: Values) => sendMessageWrap(id, values),
    {
      onMutate: async values => {
        if (onMutateSendMessage) onMutateSendMessage(values.resetBody);

        if (chatType === 'FORM') {
          clearFormDetailUnreadMessages(id);
          await queryClient.cancelQueries(formKeys.detail(id));
        } else {
          clearDetailUnreadMessages(id);
          clearTicketDetailUnreadMessages(id);
          await queryClient.cancelQueries(chatKeys.detail(id));
        }
        const newMessage = createMessage(
          user,
          values,
          MessageStatus.PENDING,
          chatType,
          !!matchFormChat,
          id,
          messageToReply?.id,
        );

        if (chatType === 'FORM') {
          pushFormDetailMessage(id, newMessage);
        } else {
          pushChatDetailMessage(id, newMessage);
        }
        return { messageId: newMessage.id };
      },
      onError: (error, values, context: any) => {
        showGeneralError(error, t('SEND_MESSAGE_ERROR'));

        const newMessage = createMessage(
          user,
          values,
          MessageStatus.ERROR,
          chatType,
          !!matchFormChat,
          id,
          messageToReply?.id,
        );

        if (chatType === 'FORM') {
          replaceFormDetailMessage(id, context.messageId, newMessage);
        } else {
          replaceChatDetailMessage(id, context.messageId, newMessage);
        }
      },
      onSuccess: (response: any, values, context: any) => {
        if (onSuccessSendMessage) onSuccessSendMessage();

        addMessageUser(
          response.data,
          user,
          chatType,
          !!matchFormChat,
          id,
          messageToReply?.id,
        );

        if (chatType === 'FORM') {
          replaceFormDetailMessage(id, context.messageId, response.data);
        } else {
          replaceChatDetailMessage(id, context.messageId, response.data);
        }
      },
    },
  );

  return { sendMessageMutate, isLoading };
};

export default useSendChatMessage;
