import { useMutation, useQueryClient } from 'react-query';

import { visitTask } from 'src/pages/dashboard/serviceManagement/services';
import {
  type Task,
  type VisitTaskBody,
} from 'src/pages/dashboard/serviceManagement/types';

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

type VisitTaskParams = {
  taskId: string;
  body?: VisitTaskBody;
};

const clearBubbleInCache = (
  taskId: string,
  body: VisitTaskBody | undefined,
  oldData: unknown,
): unknown => {
  if (!oldData) return oldData;

  // The backend always emits BUBBLE_DELETED on `visit`, so the bubble can be
  // cleared optimistically. `unreadCommentsCount` is only guaranteed to be
  // zeroed when an explicit read-acknowledgement was sent in the body; for
  // bodyless calls we leave it alone and let the next refetch reconcile.
  const shouldClearUnread = !!body?.lastReadCommentId || !!body?.commentsViewed;

  const clearTask = (task: Task) => {
    if (task.id !== taskId) return task;
    return shouldClearUnread
      ? { ...task, bubbleCount: 0, unreadCommentsCount: 0 }
      : { ...task, bubbleCount: 0 };
  };

  const asInfinite = oldData as {
    pages?: Array<{ data?: { items?: Task[] } }>;
  };
  if (Array.isArray(asInfinite?.pages)) {
    return {
      ...asInfinite,
      pages: asInfinite.pages.map(page => ({
        ...page,
        data: {
          ...page.data,
          items: page.data?.items?.map(clearTask) ?? page.data?.items,
        },
      })),
    };
  }

  const asPaginated = oldData as { data?: { items?: Task[] } };
  if (Array.isArray(asPaginated?.data?.items)) {
    return {
      ...asPaginated,
      data: {
        ...asPaginated.data,
        items: asPaginated.data!.items!.map(clearTask),
      },
    };
  }

  return oldData;
};

const useVisitTask = () => {
  const queryClient = useQueryClient();
  return useMutation(
    ({ taskId, body }: VisitTaskParams) => visitTask(taskId, body),
    {
      onSuccess: (_, { taskId, body }) => {
        queryClient.setQueriesData(
          serviceManagementKeys.tasks.all(),
          (old: unknown) => clearBubbleInCache(taskId, body, old),
        );
      },
      onError: () => {
        // Best-effort; visit is idempotent on the backend. Avoid global handler.
      },
    },
  );
};

export default useVisitTask;
