import { useEffect } from 'react';

import { queryClient } from 'src/config/react-query';
import { SocketContextValue } from 'src/contexts/SocketContext';
import { State, Task } from 'src/pages/dashboard/serviceManagement/types';

import { serviceManagementKeys } from '../queries';

type CommentUpdate = {
  socket: SocketContextValue;
  event: string;
  params?: Record<string, any>;
  callback?: (newComment: any) => void;
};

type NewComment = {
  id: string;
  task: { id: string } & Partial<Task>;
  taskId: string | null;
  taskState: State;
};

const useTaskCommentsUpdater = ({
  socket,
  event,
  params,
  callback,
}: CommentUpdate) => {
  useEffect(() => {
    const handleNewComment = (newComment: NewComment) => {
      if (params) {
        queryClient.setQueryData(
          serviceManagementKeys.tasks.list(params),
          // Replace only the task associated with the new comment for better performance (no need to refetch all tasks)
          (oldData: any) => {
            if (!oldData) {
              return oldData;
            }
            // Handle both standard queries and infinite queries
            const isInfiniteData = Array.isArray((oldData as any)?.pages);

            if (isInfiniteData) {
              const updatedPages = (oldData as any).pages?.map((page: any) => {
                if (!page?.data?.items) return page;
                return {
                  ...page,
                  data: {
                    ...page.data,
                    items: page.data.items.map((task: Task) =>
                      task.id === newComment.task.id
                        ? {
                            ...task,
                            unreadCommentsCount:
                              (task.unreadCommentsCount ?? 0) + 1,
                            bubbleCount: (task.bubbleCount ?? 0) + 1,
                          }
                        : task,
                    ),
                  },
                };
              });

              const newInfiniteData = {
                ...(oldData as any),
                pages: updatedPages,
              };
              return newInfiniteData;
            }

            const updatedStandardData = {
              ...(oldData as any),
              data: {
                ...(oldData as any)?.data,
                items: (oldData as any)?.data?.items?.map((task: Task) =>
                  task.id === newComment.task.id
                    ? {
                        ...task,
                        unreadCommentsCount:
                          (task.unreadCommentsCount ?? 0) + 1,
                        bubbleCount: (task.bubbleCount ?? 0) + 1,
                      }
                    : task,
                ),
              },
            };
            return updatedStandardData;
          },
        );
      }
      queryClient.invalidateQueries(
        serviceManagementKeys.comments.list(newComment.task.id),
      );
      callback && callback(newComment);
    };

    socket.listenEvent(event, handleNewComment);

    return () => {
      socket.closeEvent(event, handleNewComment);
    };
  }, [socket, params, event]);
};

export default useTaskCommentsUpdater;
