import {
  useInfiniteQuery,
  useMutation,
  useQuery,
  useQueryClient,
} from "@tanstack/react-query";
import { ServiceProjectRepository } from "../repositories/ServiceProjectRepository";
import showToast from "../services/toastService";

//#region Service Project
export const useServiceProjects = (pageSize, pageNumber) => {
  return useQuery({
    queryKey: ["serviceProjects", pageSize, pageNumber],
    queryFn: async () => {
      const response = await ServiceProjectRepository.GetServiceProjects(
        pageSize,
        pageNumber
      );
      return response.data;
    },
  });
};
export const useServiceProject = (projectId) => {
  return useQuery({
    queryKey: ["serviceProject", projectId],
    queryFn: async () => {
      const response = await ServiceProjectRepository.GetServiceProject(
        projectId
      );
      return response.data;
    },
    enabled: !!projectId,
  });
};

export const useServiceProjectTeam = (projectId, isActive) => {
  return useQuery({
    queryKey: ["serviceProjectTeam", projectId, isActive],
    queryFn: async () => {
      const response = await ServiceProjectRepository.GetAllocatedEmployees(
        projectId,
        isActive
      );
      return response.data;
    },
    enabled: !!projectId,
  });
};
export const useCreateServiceProject = (onSuccessCallback) => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (playload) =>
      await ServiceProjectRepository.CreateServiceProject(playload),
    onSuccess: (data, variables) => {
      queryClient.invalidateQueries({ queryKey: ["serviceProjects"] });
      if (onSuccessCallback) onSuccessCallback();
      showToast("Project created successfully", "success");
    },
    onError: (error) => {
      showToast(
        error?.response?.data?.message ||
          error.message ||
          "Failed to delete task",
        "error"
      );
    },
  });
};
export const useUpdateServiceProject = (onSuccessCallback) => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({ id, payload }) => {
      return await ServiceProjectRepository.UpdateServiceProject(id, payload);
    },
    onSuccess: (data, variables) => {
      queryClient.invalidateQueries({ queryKey: ["serviceProjects"] });
      queryClient.invalidateQueries({
        queryKey: ["serviceProject", variables.id],
      });
      if (onSuccessCallback) onSuccessCallback();
      showToast("Project updated successfully", "success");
    },
    onError: (error) => {
      showToast(
        error?.response?.data?.message ||
          error.message ||
          "Failed to update project",
        "error"
      );
    },
  });
};

export const useActiveInActiveServiceProject = (onSuccessCallback) => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id, status) => {
      return await ServiceProjectRepository.DeleteServiceProject(id, status);
    },
    onSuccess: (data, variables) => {
      queryClient.invalidateQueries({ queryKey: ["serviceProjects"] });
      if (onSuccessCallback) onSuccessCallback();
      showToast(
        `Project ${status ? "restored" : "deleted"} successfully`,
        "success"
      );
    },
    onError: (error) => {
      showToast(
        error?.response?.data?.message ||
          error.message ||
          "Failed to update project",
        "error"
      );
    },
  });
};

export const useAllocationServiceProjectTeam = (onSuccessCallback) => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async ({ payload, isActive }) =>
      await ServiceProjectRepository.AllocateEmployee(payload),
    onSuccess: (data, variables) => {
      queryClient.invalidateQueries({ queryKey: ["serviceProjectTeam"] });
      if (onSuccessCallback) onSuccessCallback();
      if (variables.isActive) {
        showToast(
          `${variables?.payload.length} Employee allocated successfully`,
          "success"
        );
      } else {
        showToast(`Employee removed successfully`, "success");
      }
    },
    onError: (error) => {
      showToast(
        error?.response?.data?.message ||
          error.message ||
          "Failed to update project",
        "error"
      );
    },
  });
};

//#endregion

//#region Service Jobs

export const useServiceProjectJobs = (
  pageSize,
  pageNumber,
  isActive = true,
  project
) => {
  return useQuery({
    queryKey: ["serviceProjectJobs", pageSize, pageNumber, isActive, project],
    queryFn: async () => {
      const resp = await ServiceProjectRepository.GetJobList(
        pageSize,
        pageNumber,
        isActive,
        project
      );
      return resp.data;
    },
  });
};
export const useJobComments = (jobId, pageSize, pageNumber) => {
  return useInfiniteQuery({
    queryKey: ["jobComments", jobId, pageSize],

    queryFn: async ({ pageParam = pageNumber }) => {
      const resp = await ServiceProjectRepository.GetJobComment(
        jobId,
        pageSize,
        pageParam
      );
      return resp.data;
    },

    initialPageParam: pageNumber,

    getNextPageParam: (lastPage, allPages) => {
      if (!lastPage?.data?.length) return null;

      return allPages.length + pageNumber;
    },
  });
};
export const useJobTags = () => {
  return useQuery({
    queryKey: ["Job_Tags"],
    queryFn: async () => await ServiceProjectRepository.GetJobTags(),
  });
};

export const useServiceProjectJobDetails = (job) => {
  return useQuery({
    queryKey: ["service-job", job],
    queryFn: async () => {
      const resp = await ServiceProjectRepository.GetJobDetails(job);
      return resp.data;
    },
    enabled: !!job,
  });
};
export const useAddCommentJob = (onSuccessCallback) => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (data) => await ServiceProjectRepository.AddComment(data),
    onSuccess: (data, variables) => {
      queryClient.invalidateQueries({
        queryKey: ["jobComments", variables?.jobTicketId],
      });
      if (onSuccessCallback) onSuccessCallback();
      showToast("Comment added successfully", "success");
    },
    onError: (error) => {
      showToast(
        error?.response?.data?.message ||
          error.message ||
          "Failed to update project",
        "error"
      );
    },
  });
};

export const useCreateServiceProjectJob = (onSuccessCallback) => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (payload) => {
      return await ServiceProjectRepository.CreateJob(payload);
    },
    onSuccess: (data, variables) => {
      queryClient.invalidateQueries({ queryKey: ["serviceProjectJobs"] });

      if (onSuccessCallback) onSuccessCallback();
      showToast("Job Created successfully", "success");
    },
    onError: (error) => {
      showToast(
        error?.response?.data?.message ||
          error.message ||
          "Failed to update project",
        "error"
      );
    },
  });
};

export const useUpdateServiceProjectJob = (onSuccessCallback) => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async ({ id, payload }) => {
      // Call the repository patch
      const resp = await ServiceProjectRepository.UpdateJob(id, payload);

      return resp;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["serviceProjectJobs"] });
      queryClient.invalidateQueries({ queryKey: ["service-job"] });
      if (onSuccessCallback) onSuccessCallback();
      showToast("Job Updated successfully", "success");
    },
    onError: (error) => {
      showToast(
        error?.response?.data?.message ||
          error.message ||
          "Failed to update project",
        "error"
      );
    },
  });
};

//#endregion
