import {
  API_ENDPOINTS,
  companiesService,
  companyCategoriesService,
  type TCompanyCategoryApiResponse,
} from "@/lib/api";
import {
  useInfiniteQuery,
  useMutation,
  useQuery,
  useQueryClient,
} from "@tanstack/react-query";
import { useRouter } from "next/navigation";
import { useCallback, useMemo } from "react";
import { toast } from "react-toastify";

export const useCreateCompany = () => {
  const queryClient = useQueryClient();
  const router = useRouter();
  const mutationKey = useMemo(() => [API_ENDPOINTS.COMPANIES, "create"], []);
  return useMutation({
    mutationKey,
    mutationFn: companiesService.createCompany,
    onSuccess: () => {
      toast.success("Company created successfully");
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.COMPANIES],
      });
      router.push("/companies");
    },
  });
};

export const useUpdateCompany = (id: string) => {
  const queryClient = useQueryClient();
  const router = useRouter();
  const mutationKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.UPDATE(id), "update"],
    [id],
  );
  return useMutation({
    mutationKey,
    mutationFn: companiesService.updateCompany,
    onSuccess: () => {
      toast.success("Company updated successfully");
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.COMPANIES.READ_ALL],
      });
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.COMPANIES.READ_ALL, "details"],
      });
      router.push("/companies");
    },
  });
};

export const useCompanyDetails = (id: string) => {
  const queryKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.READ_ALL, id, "details"],
    [id],
  );
  return useQuery({
    queryKey,
    queryFn: () => companiesService.companyDetails(id),
  });
};
export const useUploadCompanyDocuments = (id: string) => {
  const queryClient = useQueryClient();
  const mutationKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.DOCUMENTS(id), "upload-documents"],
    [id],
  );
  return useMutation({
    mutationKey,
    mutationFn: (files: File[]) =>
      companiesService.uploadDocuments({ id, files }),
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.COMPANIES.READ_ALL, id, "details"],
      });
    },
  });
};

export const useDeleteCompanyQuery = (successCallback?: () => void) => {
  const queryClient = useQueryClient();
  const mutationKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.DELETE, "delete-company"],
    [],
  );
  return useMutation({
    mutationKey,
    mutationFn: companiesService.deleteCompany,
    onSuccess: (response: { data: { message: string } }) => {
      toast.success(response.data.message);
      if (successCallback) {
        successCallback();
      }
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.COMPANIES.READ_ALL],
      });
    },
  });
};
export const useCompanyFullList = (options?: { enabled?: boolean }) => {
  const enabled = options?.enabled ?? true;
  return useQuery({
    queryKey: ["READ ALL Companies"],
    queryFn: companiesService.getCompanies,
    enabled,
  });
};
export const useCompaniesQuery = (params?: Record<string, any>) => {
  const queryKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.READ_ALL, params],
    [params],
  );
  return useQuery({
    queryKey,
    queryFn: () => companiesService.getCompanies({ ...params }),
  });
};

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

  return useInfiniteQuery({
    queryKey,

    queryFn: ({ pageParam = 0 }) =>
      companiesService.getCompanies({ ...params, offset: pageParam }),

    initialPageParam: 0,
    enabled,

    getNextPageParam: (lastPage: any) => {
      const { offset, limit, total } = lastPage.meta;

      const nextOffset = offset + limit;

      return nextOffset < total ? nextOffset : undefined;
    },
  });
};
export const useCompanyCategoriesQuery = (params?: Record<string, any>) => {
  const queryKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.CATEGORIES.READ_ALL, params],
    [params],
  );
  return useQuery({
    queryKey,
    queryFn: () => companyCategoriesService.getCategories({ ...params }),
  });
};
export const useCreateCompanyCategory = (successCallback?: () => void) => {
  const queryClient = useQueryClient();
  const router = useRouter();
  const mutationKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.CATEGORIES, "create"],
    [],
  );
  return useMutation({
    mutationKey,
    mutationFn: companyCategoriesService.createCategory,
    onSuccess: (response: { data: { message: string } }) => {
      toast.success(response.data.message);
      if (successCallback) {
        successCallback();
      }
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.COMPANIES.CATEGORIES.READ_ALL],
      });
      router.push("/company-categories");
    },
  });
};
export const useDeleteCompanyCategoryQuery = (successCallback?: () => void) => {
  const queryClient = useQueryClient();
  const mutationKey = useMemo(
    () => [
      API_ENDPOINTS.COMPANIES.CATEGORIES.DELETE,
      "delete-company-category",
    ],
    [],
  );
  return useMutation({
    mutationKey,
    mutationFn: companyCategoriesService.deleteCategory,
    onSuccess: (response: { data: { message: string } }) => {
      toast.success(response.data.message);
      if (successCallback) {
        successCallback();
      }
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.COMPANIES.CATEGORIES.READ_ALL],
      });
    },
  });
};
export const useToggleCompanyCategoryPublished = () => {
  const queryClient = useQueryClient();
  const updateOptimisticCategories = useCallback((categoryId: string) => {
    queryClient.setQueriesData<TCompanyCategoryApiResponse>(
      {
        queryKey: [API_ENDPOINTS.COMPANIES.CATEGORIES.READ_ALL],
        exact: false,
      },
      (previousList) => {
        if (!previousList?.data?.categories) {
          return previousList;
        }
        return {
          ...previousList,
          data: {
            ...previousList.data,
            categories: previousList.data.categories.map((category) =>
              category.id === categoryId
                ? { ...category, published: !category.published }
                : category,
            ),
          },
        };
      },
    );
  }, [queryClient]);
  const mutationKey = useMemo(
    () => [
      API_ENDPOINTS.COMPANIES.CATEGORIES.TOGGLE_PUBLISHED("published"),
      "published",
    ],
    [],
  );
  return useMutation({
    mutationKey,
    mutationFn: companyCategoriesService.togglePublished,
    onSuccess: (toggleResponse, categoryId: string) => {
      const responseBody = toggleResponse as {
        data?: { message?: string };
        message?: string;
      };
      const toastMessage =
        responseBody.data?.message ?? responseBody.message;
      if (toastMessage) {
        toast.success(toastMessage);
      }
      // Sync cache only — avoid invalidateQueries here: it refetches and produces a
      // second `data` reference, which retriggers table row GSAP animations twice.
      updateOptimisticCategories(categoryId);
    },
  });
};
export const useCompanyCategoriesDetails = (id: string) => {
  const queryKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.CATEGORIES.DETAILS(id), "details"],
    [id],
  );
  return useQuery({
    queryKey,
    queryFn: () => companyCategoriesService.getSingleCategory(id),
  });
};
export const useUpdateCompanyCategories = (id: string) => {
  const queryClient = useQueryClient();
  const router = useRouter();
  const mutationKey = useMemo(
    () => [API_ENDPOINTS.COMPANIES.CATEGORIES.UPDATE(id), "update"],
    [id],
  );
  return useMutation({
    mutationKey,
    mutationFn: companyCategoriesService.updateCategories,
    onSuccess: ({ data }: { data: { message: string } }) => {
      toast.success(data.message);
      queryClient.invalidateQueries({
        queryKey: [API_ENDPOINTS.COMPANIES.CATEGORIES.READ_ALL],
      });
      router.push("/company-categories");
    },
  });
};
