import { useEffect } from 'react';
import { useQueryClient } from 'react-query';

import { type AxiosResponse } from 'axios';

import { EVENTS_SOCKETS } from 'src/constants/sockets';
import { useSocket } from 'src/contexts/SocketContext';
import {
  type State,
  type Task,
} from 'src/pages/dashboard/serviceManagement/types';

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

type TaskStateUpdateSocketData = {
  catalogItemId: string;
  taskId: string;
  newState: State;
  initiatorId?: number;
  assigneeId?: number;
  userUpdatedAt?: string;
};

const useTaskStateUpdater = (taskId: string) => {
  const socket = useSocket();
  const queryClient = useQueryClient();

  useEffect(() => {
    const handleNewState = (newStateData: TaskStateUpdateSocketData) => {
      // Only update the state if this task is the one that changed
      if (!newStateData || taskId !== newStateData.taskId) {
        return;
      }

      const updatedState = newStateData?.newState;

      queryClient.setQueryData<AxiosResponse<Task> | undefined>(
        serviceManagementKeys.tasks.detail(taskId),
        previousData => {
          if (!previousData || !updatedState) {
            return previousData;
          }

          return {
            ...previousData,
            data: {
              ...previousData.data,
              state: {
                id: updatedState.id,
                name: updatedState.name,
                terminal: updatedState.terminal,
              },
            },
          };
        },
      );
      queryClient.invalidateQueries(
        serviceManagementKeys.states.list(updatedState.id),
      );
    };

    socket.listenEvent(
      EVENTS_SOCKETS.SERVICE_MANAGER_TASK_NEW_STATE,
      handleNewState,
    );

    return () => {
      socket.closeEvent(
        EVENTS_SOCKETS.SERVICE_MANAGER_TASK_NEW_STATE,
        handleNewState,
      );
    };
  }, [socket, queryClient, taskId]);
};

export default useTaskStateUpdater;
