import { useMutation, useQueryClient } from '@tanstack/react-query';
import {
  archiveSprint,
  cancelSprint,
  closeSprint,
  createBacklogItem,
  createProject,
  createSprint,
  deleteSprint,
  duplicateSprint,
  moveTicketToSprint,
  moveTicketToBacklog,
  reorderBacklog,
  restoreSprint,
  startSprint,
  updateSprint,
} from '@/features/projects/services/projectService';
import { backlogQueryKey } from '@/features/projects/hooks/useProjectBacklog';
import { projectQueryKey } from '@/features/projects/hooks/useProject';
import { sprintsQueryKey } from '@/features/projects/hooks/useProjectSprints';
import { sprintTicketsQueryKey } from '@/features/projects/hooks/useSprintTickets';

export function useProjectMutations() {
  const queryClient = useQueryClient();

  const createProjectMutation = useMutation({
    mutationFn: createProject,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['projects'] }),
  });

  const createBacklogMutation = useMutation({
    mutationFn: ({ projectId, payload }: { projectId: string; payload: Record<string, unknown> }) =>
      createBacklogItem(projectId, payload),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: backlogQueryKey(vars.projectId) });
      queryClient.invalidateQueries({ queryKey: projectQueryKey(vars.projectId) });
    },
  });

  const createSprintMutation = useMutation({
    mutationFn: ({ projectId, payload }: { projectId: string; payload: Record<string, unknown> }) =>
      createSprint(projectId, payload),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const moveToSprintMutation = useMutation({
    mutationFn: ({
      projectId,
      ticketId,
      sprintId,
    }: {
      projectId: string;
      ticketId: string;
      sprintId: string;
    }) => moveTicketToSprint(projectId, ticketId, sprintId),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: backlogQueryKey(vars.projectId) });
      queryClient.invalidateQueries({ queryKey: sprintTicketsQueryKey(vars.projectId, vars.sprintId) });
    },
  });

  const reorderBacklogMutation = useMutation({
    mutationFn: ({ projectId, ticketIds }: { projectId: string; ticketIds: string[] }) =>
      reorderBacklog(projectId, ticketIds),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: backlogQueryKey(vars.projectId) });
    },
  });

  const startSprintMutation = useMutation({
    mutationFn: ({ projectId, sprintId }: { projectId: string; sprintId: string }) =>
      startSprint(projectId, sprintId),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const moveToBacklogMutation = useMutation({
    mutationFn: ({ projectId, ticketId }: { projectId: string; ticketId: string }) =>
      moveTicketToBacklog(projectId, ticketId),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: backlogQueryKey(vars.projectId) });
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const closeSprintMutation = useMutation({
    mutationFn: ({
      projectId,
      sprintId,
      closureOverrideReason,
    }: {
      projectId: string;
      sprintId: string;
      closureOverrideReason?: string;
    }) => closeSprint(projectId, sprintId, closureOverrideReason),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const updateSprintMutation = useMutation({
    mutationFn: ({
      projectId,
      sprintId,
      payload,
    }: {
      projectId: string;
      sprintId: string;
      payload: Record<string, unknown>;
    }) => updateSprint(projectId, sprintId, payload),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const deleteSprintMutation = useMutation({
    mutationFn: ({ projectId, sprintId }: { projectId: string; sprintId: string }) =>
      deleteSprint(projectId, sprintId),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const cancelSprintMutation = useMutation({
    mutationFn: ({ projectId, sprintId }: { projectId: string; sprintId: string }) =>
      cancelSprint(projectId, sprintId),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const archiveSprintMutation = useMutation({
    mutationFn: ({ projectId, sprintId }: { projectId: string; sprintId: string }) =>
      archiveSprint(projectId, sprintId),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const restoreSprintMutation = useMutation({
    mutationFn: ({ projectId, sprintId }: { projectId: string; sprintId: string }) =>
      restoreSprint(projectId, sprintId),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  const duplicateSprintMutation = useMutation({
    mutationFn: ({ projectId, sprintId }: { projectId: string; sprintId: string }) =>
      duplicateSprint(projectId, sprintId),
    onSuccess: (_d, vars) => {
      queryClient.invalidateQueries({ queryKey: sprintsQueryKey(vars.projectId) });
    },
  });

  return {
    createProjectMutation,
    createBacklogMutation,
    createSprintMutation,
    moveToSprintMutation,
    reorderBacklogMutation,
    startSprintMutation,
    closeSprintMutation,
    updateSprintMutation,
    deleteSprintMutation,
    cancelSprintMutation,
    archiveSprintMutation,
    restoreSprintMutation,
    duplicateSprintMutation,
    moveToBacklogMutation,
  };
}
