import { type AxiosResponse } from 'axios';

import { queryClient } from 'src/config/react-query';
import {
  type ApprovalRequest,
  type CategorizedHourApprovalStep,
  type CategorizedHourStatusUpdatedSocket,
} from 'src/types/timeTracking';

import {
  invalidateCategorizedHoursApprovalQueries,
  timeTrackingKeys,
} from './queries';

const mergeSteps = (
  current: CategorizedHourApprovalStep[] | undefined,
  incoming: CategorizedHourStatusUpdatedSocket['steps'],
): CategorizedHourApprovalStep[] | undefined => {
  if (!current) return current;
  const incomingById = new Map(incoming.map(s => [s.stepId, s.status]));
  return current.map(step => {
    const newStatus = incomingById.get(String(step.id));
    return newStatus ? { ...step, state: newStatus } : step;
  });
};

export const handleCategorizedHourStatusUpdated = (
  payload: CategorizedHourStatusUpdatedSocket,
) => {
  queryClient.setQueryData<AxiosResponse<ApprovalRequest> | undefined>(
    timeTrackingKeys.categorizedHours.detail(payload.categorizedHourId),
    old =>
      old
        ? {
            ...old,
            data: {
              ...old.data,
              status: payload.hourStatus,
              approvalSteps: mergeSteps(old.data.approvalSteps, payload.steps),
            },
          }
        : old,
  );

  queryClient.refetchQueries(
    timeTrackingKeys.categorizedHours.detail(payload.categorizedHourId),
  );
  invalidateCategorizedHoursApprovalQueries();
};
