import { useCallback } from 'react';
import { useLocation, matchPath } from 'react-router-dom';

import { queryClient } from 'src/config/react-query';
import { useAuth } from 'src/contexts/JWTContext';
import useUnreadChats from 'src/hooks/useUnreadChats';
import { clearChatNotifications } from 'src/services/chats';
import { FormType } from 'src/types/forms';
import {
  canAddMessage,
  addLastMessageChat,
  isGroupChatAdmin,
} from 'src/utils/chats';

import { setMessageListData } from 'src/components/dashboard/chat/queries';
import {
  formKeys,
  setFormData,
  moveFirstFormRequestListData,
  moveFirstFormChatListData,
  setFormCompletedListData,
  addFormChatNotification,
  addFormRequestNotification,
  invalidateFormsNotifications,
  formInFirstPage,
  formAgentInFirstPage,
  refetchFormsListCompleted,
  refetchAssignedForms,
  updateStaticsListCompleted,
} from 'src/components/dashboard/form/queries';
import { formSkeletonRoutes } from 'src/components/dashboard/form/routes';

const PATH_FORM_CHAT_DETAIL = formSkeletonRoutes.form.detail('form');
const PATH_FORM_REQUEST_DETAIL = formSkeletonRoutes.requests.detail('form');

const useForm = () => {
  const { user } = useAuth();
  const location = useLocation();
  const unread = useUnreadChats();

  const formChatDetailMatch = matchPath(
    {
      path: PATH_FORM_CHAT_DETAIL,
      end: true,
    },
    location.pathname,
  );

  const formRequestDetailMatch = matchPath(
    {
      path: PATH_FORM_REQUEST_DETAIL,
      end: true,
    },
    location.pathname,
  );

  const currentChatId = formChatDetailMatch
    ? Number(formChatDetailMatch?.params?.id)
    : Number(formRequestDetailMatch?.params?.id);

  const closeFormChat = useCallback(
    (formListItem: any) => {
      const chatId = formListItem?.chat?.id;
      const formId = formListItem?.form?.id;
      const messageUserId = formListItem?.chat?.lastMessage?.userId;

      if (!chatId || !messageUserId) return;

      if (
        chatId !== currentChatId &&
        messageUserId !== user.id &&
        formListItem.status !== 'UNASSIGNED' &&
        !unread.has(chatId)
      ) {
        unread.add(chatId);
      } else if (chatId === currentChatId && messageUserId !== user.id) {
        clearChatNotifications(chatId);
      }

      setMessageListData(
        Number(chatId),
        oldData => {
          if (!oldData) return oldData;

          if (canAddMessage(formListItem, oldData.items)) {
            oldData.items = addLastMessageChat(oldData.items, formListItem);
          }

          return oldData;
        },
        0,
      );

      updateStaticsListCompleted();

      if (formInFirstPage(formKeys.listCompleted(FormType.FORM), formId)) {
        setFormCompletedListData(Number(chatId), oldData => {
          if (!oldData) return oldData;

          oldData.lastMessage = formListItem.chat.lastMessage;

          if (chatId !== currentChatId && messageUserId !== user.id) {
            oldData.unreadMessages++;
          } else {
            oldData.unreadMessages = 0;
          }

          return oldData;
        });

        moveFirstFormChatListData(chatId);
      } else {
        refetchFormsListCompleted();
      }

      if (formAgentInFirstPage(formKeys.assignedForms(), formId)) {
        setFormData(chatId, formItem => {
          formItem.lastMessage = formListItem.chat.lastMessage;
          return formItem;
        });
        moveFirstFormRequestListData(chatId);
      } else {
        refetchAssignedForms();
      }

      if (chatId !== currentChatId) {
        invalidateFormsNotifications();
      }
    },
    [currentChatId, unread, user.id],
  );

  const addFormMessage = useCallback(
    (formListItem: any) => {
      const chatId = formListItem?.chat?.id;
      const messageUserId = formListItem?.chat?.lastMessage?.userId;

      if (!chatId || !messageUserId) return;

      if (
        chatId !== currentChatId &&
        messageUserId !== user.id &&
        formListItem.status !== 'UNASSIGNED' &&
        !unread.has(chatId)
      ) {
        unread.add(chatId);
        addFormChatNotification();
      } else if (chatId === currentChatId && messageUserId !== user.id) {
        clearChatNotifications(chatId);
      }

      setFormCompletedListData(Number(chatId), oldData => {
        if (!oldData) return oldData;

        oldData.lastMessage = formListItem.chat.lastMessage;

        if (chatId !== currentChatId && messageUserId !== user.id) {
          oldData.unreadMessages++;
        } else {
          oldData.unreadMessages = 0;
        }

        return oldData;
      });

      setMessageListData(
        Number(chatId),
        oldData => {
          if (!oldData) return oldData;

          if (canAddMessage(formListItem, oldData.items)) {
            oldData.items = addLastMessageChat(oldData.items, formListItem);
          }

          return oldData;
        },
        0,
      );

      refetchFormsListCompleted();
      moveFirstFormChatListData(chatId);
      queryClient.invalidateQueries(formKeys.stats());
    },
    [currentChatId, unread, user.id],
  );

  const addFormRequestMessage = useCallback(
    (formListItem: any) => {
      const chatId = formListItem?.chat?.id;
      const formId = formListItem?.form?.id;
      const messageUserId = formListItem?.chat?.lastMessage?.userId;

      if (!chatId || !messageUserId) return;

      if (
        chatId !== currentChatId &&
        messageUserId !== user.id &&
        formListItem.status !== 'UNASSIGNED' &&
        !unread.has(chatId)
      ) {
        unread.add(chatId);
        addFormRequestNotification();
      } else if (chatId === currentChatId && messageUserId !== user.id) {
        clearChatNotifications(chatId);
        queryClient.invalidateQueries(formKeys.redBubblesAgent());
      }

      if (formInFirstPage(formKeys.listCompleted(FormType.FORM), formId)) {
        setFormCompletedListData(Number(chatId), oldData => {
          if (!oldData) return oldData;

          oldData.lastMessage = formListItem.chat.lastMessage;

          return oldData;
        });
      } else {
        refetchFormsListCompleted();
      }

      if (formAgentInFirstPage(formKeys.assignedForms(), formId)) {
        setFormData(chatId, formItem => {
          formItem.lastMessage = formListItem.chat.lastMessage;

          if (chatId !== currentChatId && messageUserId !== user.id) {
            formItem.unreadMessages++;
          } else {
            formItem.unreadMessages = 0;
          }

          return formItem;
        });

        moveFirstFormRequestListData(chatId);
      } else {
        refetchAssignedForms();
      }

      if (chatId !== currentChatId) {
        invalidateFormsNotifications();
        queryClient.invalidateQueries(formKeys.redBubblesAgent());
      }
    },
    [currentChatId, unread, user.id],
  );

  const addUnreadFormChat = useCallback(
    (chatListItem: any) => {
      const chatId = chatListItem?.chat?.id;
      const isAdmin = isGroupChatAdmin(chatListItem?.chat?.otherUsers, user.id);

      if (!chatId || isAdmin) return;

      addFormChatNotification();
    },
    [user.id],
  );

  const deleteForm = useCallback(() => {
    queryClient.invalidateQueries(formKeys.listCompleted(FormType.FORM));
    queryClient.invalidateQueries(formKeys.listAvailable(FormType.FORM));
    queryClient.invalidateQueries(formKeys.unassignedForms());
    queryClient.invalidateQueries(formKeys.assignedForms());
    queryClient.invalidateQueries(formKeys.closedForms());
    queryClient.invalidateQueries(formKeys.redBubblesAgent());
    invalidateFormsNotifications();
  }, []);

  return {
    addUnreadFormChat,
    addFormMessage,
    addFormRequestMessage,
    closeFormChat,
    deleteForm,
  };
};

export default useForm;
