import { useEffect } from 'react';

import { EVENTS_SOCKETS } from 'src/constants/sockets';
import { useSocket } from 'src/contexts/SocketContext';
import { userIsOnGroupPage } from 'src/utils/groups';

import {
  invalidateGroupDetails,
  invalidateGroupPendingApprovalPostList,
  invalidateGroupPostList,
  invalidatePinAndPostList,
  updateGroupMembersCount,
} from '../queries';

export const useGroupDetailSockets = () => {
  const socket = useSocket();

  useEffect(() => {
    const updateMemberCount = ({
      groupId,
      membersCount: newMembersCount,
    }: {
      groupId: number;
      membersCount: number;
    }) => {
      const isOnUpdatedGroup = userIsOnGroupPage(groupId);
      if (isOnUpdatedGroup) updateGroupMembersCount(groupId, newMembersCount);
    };

    const refetchGroup = ({ groupId }: { groupId: number }) => {
      const isOnUpdatedGroup = userIsOnGroupPage(groupId);
      if (isOnUpdatedGroup) invalidateGroupDetails(groupId);
    };

    const addOrRemovePinnedPost = ({ groupId }: { groupId: number }) => {
      const isOnUpdatedGroup = userIsOnGroupPage(groupId);
      if (isOnUpdatedGroup) invalidatePinAndPostList(groupId);
    };

    const updatePostRequests = ({ groupId }: { groupId: number }) => {
      const isOnUpdatedGroup = userIsOnGroupPage(groupId);
      if (isOnUpdatedGroup) {
        invalidateGroupPendingApprovalPostList(groupId);
        invalidateGroupPostList(groupId);
      }
    };

    const updatePendingApprovalPostRequests = ({
      groupId,
    }: {
      groupId: number;
    }) => {
      const isOnUpdatedGroup = userIsOnGroupPage(groupId);
      if (isOnUpdatedGroup) {
        invalidateGroupPendingApprovalPostList(groupId);
      }
    };

    socket.listenEvent(EVENTS_SOCKETS.GROUP_POST_PINNED, addOrRemovePinnedPost);

    socket.listenEvent(
      EVENTS_SOCKETS.GROUP_POST_UNPINNED,
      addOrRemovePinnedPost,
    );

    socket.listenEvent(
      EVENTS_SOCKETS.GROUP_MEMBERS_COUNT_UPDATED,
      updateMemberCount,
    );

    socket.listenEvent(EVENTS_SOCKETS.GROUP_MEMBER_ROLE_UPDATED, refetchGroup);

    socket.listenEvent(EVENTS_SOCKETS.GROUP_REQUEST_CANCELED, refetchGroup);

    socket.listenEvent(
      EVENTS_SOCKETS.GROUP_REQUEST_STATUS_UPDATED,
      refetchGroup,
    );

    socket.listenEvent(
      EVENTS_SOCKETS.GROUP_HAS_PENDING_REQUESTS_UPDATED,
      refetchGroup,
    );

    socket.listenEvent(EVENTS_SOCKETS.GROUP_REQUEST_CREATED, refetchGroup);

    socket.listenEvent(
      EVENTS_SOCKETS.GROUP_POST_REQUEST_APPROVED,
      updatePostRequests,
    );

    socket.listenEvent(
      EVENTS_SOCKETS.GROUP_POST_REQUEST_REJECTED,
      updatePendingApprovalPostRequests,
    );

    return () => {
      socket.closeEvent(
        EVENTS_SOCKETS.GROUP_POST_PINNED,
        addOrRemovePinnedPost,
      );

      socket.closeEvent(
        EVENTS_SOCKETS.GROUP_POST_UNPINNED,
        addOrRemovePinnedPost,
      );

      socket.closeEvent(
        EVENTS_SOCKETS.GROUP_MEMBERS_COUNT_UPDATED,
        updateMemberCount,
      );

      socket.closeEvent(EVENTS_SOCKETS.GROUP_MEMBER_ROLE_UPDATED, refetchGroup);

      socket.closeEvent(EVENTS_SOCKETS.GROUP_REQUEST_CANCELED, refetchGroup);

      socket.closeEvent(
        EVENTS_SOCKETS.GROUP_REQUEST_STATUS_UPDATED,
        refetchGroup,
      );

      socket.closeEvent(
        EVENTS_SOCKETS.GROUP_HAS_PENDING_REQUESTS_UPDATED,
        refetchGroup,
      );

      socket.closeEvent(EVENTS_SOCKETS.GROUP_REQUEST_CREATED, refetchGroup);

      socket.closeEvent(
        EVENTS_SOCKETS.GROUP_POST_REQUEST_REJECTED,
        updatePostRequests,
      );

      socket.closeEvent(
        EVENTS_SOCKETS.GROUP_POST_REQUEST_APPROVED,
        updatePostRequests,
      );
    };
  }, [socket]);
};
