import { useUser } from "@/contexts";
import { API_ENDPOINTS, ICreateAdminCredentials, userService } from "@/lib/api";
import {
  useInfiniteQuery,
  useMutation,
  useQuery,
  useQueryClient,
} from "@tanstack/react-query";
import { useRouter } from "next/navigation";
import { useMemo } from "react";
import { toast } from "react-toastify";

const toCurrentUserUpdates = ({
  password: _password,
  ...profile
}: ICreateAdminCredentials) => profile;

export const useDeleteAdmin = (onSuccessCallback: () => void) => {
  const queryClient = useQueryClient();
  const mutationKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, "delete"], []);
  return useMutation({
    mutationKey,
    mutationFn: userService.deleteAdmin,
    onSuccess: (response) => {
      toast.info(response.data.message);
      onSuccessCallback();
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.USER.ADMINS],
      });
    },
  });
};

export const useCreateAdmin = () => {
  const queryClient = useQueryClient();
  const router = useRouter();
  const mutationKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, "create"], []);
  return useMutation({
    mutationKey,
    mutationFn: userService.createAdmin,
    onSuccess: (response) => {
      toast.success(response);
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.USER.ADMINS],
      });
      router.push("/admins");
    },
  });
};

export const useUpdateAdmin = (id: string) => {
  const queryClient = useQueryClient();
  const router = useRouter();
  const { user, syncCurrentUser } = useUser();
  const mutationKey = useMemo(
    () => [API_ENDPOINTS.USER.ADMINS, "update", id],
    [id],
  );
  return useMutation({
    mutationKey,
    mutationFn: userService.updateAdmin,
    onSuccess: (response, { id: adminId, credentials }) => {
      if (user?.id === adminId) {
        syncCurrentUser(toCurrentUserUpdates(credentials));
      }

      toast.success(response);
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.USER.ADMINS],
      });
      router.push("/admins");
    },
  });
};

export const useAdminDetails = (id: string) => {
  const queryKey = useMemo(
    () => [API_ENDPOINTS.USER.ADMINS, "details", id],
    [id],
  );
  return useQuery({
    queryKey,
    queryFn: () => userService.adminDetails(id),
  });
};

export const useAdminListInfiniteQuery = (
  params?: Record<string, any>,
  options?: { enabled?: boolean },
) => {
  const enabled = options?.enabled ?? true;
  const queryKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, params], [params]);

  return useInfiniteQuery({
    queryKey,

    queryFn: ({ pageParam = 0 }) =>
      userService.adminsList({ ...params, offset: pageParam }),

    initialPageParam: 0,
    enabled,

    getNextPageParam: (lastPage) => {
      if (!lastPage.meta) {
        return undefined;
      }
      const { offset, limit, total } = lastPage.meta;

      const nextOffset = offset + limit;

      return nextOffset < total ? nextOffset : undefined;
    },
  });
};

export const useGetAdminListQuery = (params?: Record<string, any>) => {
  const queryKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, params], [params]);
  return useQuery({
    queryKey,
    queryFn: () => userService.adminsList(params),
  });
};

export const useGetUsersQuery = (params?: Record<string, any>) => {
  const queryKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, params], [params]);
  return useQuery({
    queryKey,
    queryFn: () => userService.adminsList(params),
  });
};

export const useResetAdminPassword = ({
  successCallback,
}: {
  successCallback?: (password: string) => void;
} = {}) => {
  const mutationKey = useMemo(
    () => [API_ENDPOINTS.USER.ADMINS, "reset-password"],
    [],
  );
  return useMutation({
    mutationKey,
    mutationFn: userService.resetAdminPassword,
    onSuccess: (response) => {
      toast.success(response.message);
      successCallback?.(response.data.password);
    },
  });
};

export const useChangeAdminStatus = ({
  id,
  successCallback,
}: {
  id: string;
  successCallback: () => void;
}) => {
  const queryClient = useQueryClient();
  const mutationKey = useMemo(
    () => [API_ENDPOINTS.USER.CHANGE_ADMIN_STATUS(id)],
    [id],
  );
  return useMutation({
    mutationKey,
    mutationFn: userService.changeAdminStatus,
    onSuccess: ({ message }: { message: string }) => {
      successCallback();
      toast.success(message);
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.USER.ADMINS],
      });
    },
  });
};
