import {
  useMutation,
  useQuery,
  useQueryClient,
  useInfiniteQuery,
} from "@tanstack/react-query";
import { useAuthToken } from "../hooks/use-root-data";
import {
  FullProductCreate,
  FullProductUpdate,
  ProductDetail,
  ProductOwnershipCheck,
  ProductAttributeValue,
  SellerProductListItem,
  VariantStockUpdateRequest,
  VariantStockUpdateResponse,
  ProductBasePriceUpdateRequest,
  ProductBasePriceUpdateResponse,
  VariantPriceUpdateRequest,
  VariantPriceUpdateResponse,
  PaginatedSimilarProduct,
} from "../../src/api/types";
import { useToast } from "../hooks/use-toast";
import {
  createProductManagementApi,
  createApiApi,
} from "~/utils/api-client-factory";

/**
 * Custom hook to fetch all attribute values
 */
export const useAttributeValues = () => {
  const token = useAuthToken();

  return useQuery({
    queryKey: ["attributeValues"],
    queryFn: async (): Promise<ProductAttributeValue[]> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      return await productApi.apiProductV1AttributevalueList();
    },
    enabled: !!token,
  });
};

/**
 * Custom hook to fetch color attributes
 */
export const useColorAttributes = () => {
  const { data: attributeValues, isLoading, error } = useAttributeValues();

  return {
    data:
      attributeValues?.filter(
        (attr) => attr.attributeName?.toLowerCase() === "color"
      ) || [],
    isLoading,
    error,
  };
};

/**
 * Custom hook to fetch size attributes
 */
export const useSizeAttributes = () => {
  const { data: attributeValues, isLoading, error } = useAttributeValues();

  return {
    data:
      attributeValues?.filter(
        (attr) => attr.attributeName?.toLowerCase() === "size"
      ) || [],
    isLoading,
    error,
  };
};

/**
 * Custom hook to create a full product with attributes and variants
 */
export const useCreateFullProduct = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  const { toast } = useToast();

  return useMutation({
    mutationFn: async (
      productData: FullProductCreate
    ): Promise<ProductDetail> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      return await productApi.apiProductV1ProductsFullCreateCreate({
        data: productData,
      });
    },
    onSuccess: () => {
      toast({
        title: "موفق",
        description: "محصول با موفقیت ایجاد شد",
        variant: "default",
      });
      // Invalidate relevant queries
      queryClient.invalidateQueries({ queryKey: ["products"] });
      queryClient.invalidateQueries({ queryKey: ["sellerProducts"] });
    },
    onError: (error: Error) => {
      console.error("Product creation failed:", error);
      toast({
        title: "خطا",
        description: "خطا در ایجاد محصول. لطفاً دوباره تلاش کنید",
        variant: "destructive",
      });
    },
  });
};
/**
 * Custom hook to fetch seller categories
 */
export const useProductCategories = () => {
  const token = useAuthToken();
  return useQuery({
    queryKey: ["sellerCategories"],
    queryFn: async () => {
      const productApi = createProductManagementApi(token);
      return await productApi.apiProductV1CategoriesList();
    },
  });
};

/**
 * Custom hook to fetch a is-owner product
 */
export const useIsOwnerProduct = (productId: string) => {
  const token = useAuthToken();

  return useQuery({
    queryKey: ["is-owner-product", productId],
    queryFn: async (): Promise<ProductOwnershipCheck> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      return await productApi.apiProductV1ProductsIsOwnerList({
        id: productId,
      });
    },
    enabled: !!token && !!productId,
  });
};

/**
 * Custom hook to fetch a single product details
 */
export const useProductDetails = (productId: string) => {
  const token = useAuthToken();

  return useQuery({
    queryKey: ["product", productId],
    queryFn: async (): Promise<ProductDetail> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      return await productApi.apiProductV1ProductsRead({ id: productId });
    },
    enabled: !!token && !!productId,
  });
};

/**
 * Custom hook to delete a product
 */
export const useDeleteProduct = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  const { toast } = useToast();

  return useMutation({
    mutationFn: async (productId: string): Promise<void> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      return await productApi.apiProductV1ProductsDelete({ id: productId });
    },
    onSuccess: () => {
      toast({
        title: "موفق",
        description: "محصول با موفقیت حذف شد",
        variant: "default",
      });
      // Invalidate relevant queries
      queryClient.invalidateQueries({ queryKey: ["products"] });
      queryClient.invalidateQueries({ queryKey: ["sellerProducts"] });
    },
    onError: (error: Error) => {
      console.error("Product deletion failed:", error);
      toast({
        title: "خطا",
        description: "خطا در حذف محصول. لطفاً دوباره تلاش کنید",
        variant: "destructive",
      });
    },
  });
};

/**
 * Custom hook to update a product
 */
export const useUpdateProduct = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  const { toast } = useToast();

  return useMutation({
    mutationFn: async ({
      productId,
      productData,
    }: {
      productId: string;
      productData: FullProductUpdate;
    }): Promise<ProductDetail> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      return await productApi.apiProductV1ProductsPartialUpdate({
        id: productId,
        data: productData,
      });
    },
    onSuccess: (data, variables) => {
      toast({
        title: "موفق",
        description: "محصول با موفقیت به‌روزرسانی شد",
        variant: "default",
      });
      // Invalidate relevant queries
      queryClient.invalidateQueries({
        queryKey: ["product", variables.productId],
      });
      queryClient.invalidateQueries({ queryKey: ["products"] });
      queryClient.invalidateQueries({ queryKey: ["sellerProducts"] });
    },
    onError: (error: Error) => {
      console.error("Product update failed:", error);
      toast({
        title: "خطا",
        description: "خطا در به‌روزرسانی محصول. لطفاً دوباره تلاش کنید",
        variant: "destructive",
      });
    },
  });
};

/**
 * Custom hook to toggle product active status
 */
export const useToggleProductStatus = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  const { toast } = useToast();

  return useMutation({
    mutationFn: async ({
      productId,
      isActive,
    }: {
      productId: string;
      isActive: boolean;
    }): Promise<ProductDetail> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      return await productApi.apiProductV1ProductsActivatePartialUpdate({
        data: { id: productId, isActive },
      });
    },
    onSuccess: (data, variables) => {
      toast({
        title: "موفق",
        description: variables.isActive
          ? "محصول با موفقیت فعال شد"
          : "محصول با موفقیت غیرفعال شد",
        variant: "default",
      });
      // Invalidate relevant queries
      queryClient.invalidateQueries({
        queryKey: ["product", variables.productId],
      });
      queryClient.invalidateQueries({ queryKey: ["products"] });
      queryClient.invalidateQueries({ queryKey: ["sellerProducts"] });
    },
    onError: (error: Error) => {
      console.error("Product status toggle failed:", error);
      toast({
        title: "خطا",
        description: "خطا در تغییر وضعیت محصول. لطفاً دوباره تلاش کنید",
        variant: "destructive",
      });
    },
  });
};

/**
 * Custom hook to fetch seller products list using apiProductV1SellerProductsList
 */
export const useGetSellerProductsList = () => {
  const token = useAuthToken();
  const productApi = createProductManagementApi(token);

  return useQuery({
    queryKey: ["sellerProductsList"],
    queryFn: async (): Promise<SellerProductListItem[]> => {
      if (!token) throw new Error("Authentication required");

      return await productApi.apiProductV1SellerProductsList();
    },
    enabled: !!token,
    staleTime: 30 * 60 * 1000, // 30 seconds - balance between freshness and performance
  });
};

/**
 * Custom hook to update product variant stock
 */
export const useUpdateVariantStock = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  const { toast } = useToast();

  return useMutation({
    mutationFn: async ({
      variantId,
      stock,
    }: {
      variantId: string;
      stock: number;
    }): Promise<VariantStockUpdateResponse> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      const data: VariantStockUpdateRequest = {
        variantId,
        stock,
      };
      return await productApi.apiProductV1ProductsVariantsStockPartialUpdate({
        data,
      });
    },
    onSuccess: (data) => {
      toast({
        title: "موفق",
        description: "موجودی با موفقیت به‌روزرسانی شد",
        variant: "default",
      });
      // Invalidate relevant queries to refresh the data
      queryClient.invalidateQueries({ queryKey: ["sellerProductsList"] });
      queryClient.invalidateQueries({ queryKey: ["products"] });
      if (data.product) {
        queryClient.invalidateQueries({ queryKey: ["product", data.product] });
      }
    },
    onError: (error: Error) => {
      console.error("Variant stock update failed:", error);
      toast({
        title: "خطا",
        description: "خطا در به‌روزرسانی موجودی. لطفاً دوباره تلاش کنید",
        variant: "destructive",
      });
    },
  });
};

/**
 * Custom hook to update a product's base price (quick edit).
 */
export const useUpdateProductBasePrice = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  const { toast } = useToast();

  return useMutation({
    mutationFn: async ({
      productId,
      basePrice,
    }: {
      productId: string;
      basePrice: string;
    }): Promise<ProductBasePriceUpdateResponse> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      const data: ProductBasePriceUpdateRequest = {
        productId,
        basePrice,
      };
      return await productApi.apiProductV1ProductsBasePricePartialUpdate({
        data,
      });
    },
    onSuccess: (data) => {
      toast({
        title: "موفق",
        description: "قیمت با موفقیت به‌روزرسانی شد",
        variant: "default",
      });
      queryClient.invalidateQueries({ queryKey: ["sellerProductsList"] });
      queryClient.invalidateQueries({ queryKey: ["products"] });
      if (data.id) {
        queryClient.invalidateQueries({ queryKey: ["product", data.id] });
      }
    },
    onError: (error: Error) => {
      console.error("Base price update failed:", error);
      toast({
        title: "خطا",
        description: "خطا در به‌روزرسانی قیمت. لطفاً دوباره تلاش کنید",
        variant: "destructive",
      });
    },
  });
};

/**
 * Custom hook to update a single variant's price override (quick edit).
 * Pass `price: null` to clear the override and inherit the base price.
 */
export const useUpdateVariantPrice = () => {
  const token = useAuthToken();
  const queryClient = useQueryClient();
  const { toast } = useToast();

  return useMutation({
    mutationFn: async ({
      variantId,
      price,
    }: {
      variantId: string;
      price: string | null;
    }): Promise<VariantPriceUpdateResponse> => {
      if (!token) throw new Error("Authentication required");

      const productApi = createProductManagementApi(token);
      const data: VariantPriceUpdateRequest = {
        variantId,
        price,
      };
      return await productApi.apiProductV1ProductsVariantsPricePartialUpdate({
        data,
      });
    },
    onSuccess: (data) => {
      toast({
        title: "موفق",
        description: "قیمت با موفقیت به‌روزرسانی شد",
        variant: "default",
      });
      queryClient.invalidateQueries({ queryKey: ["sellerProductsList"] });
      queryClient.invalidateQueries({ queryKey: ["products"] });
      if (data.product) {
        queryClient.invalidateQueries({ queryKey: ["product", data.product] });
      }
    },
    onError: (error: Error) => {
      console.error("Variant price update failed:", error);
      toast({
        title: "خطا",
        description: "خطا در به‌روزرسانی قیمت. لطفاً دوباره تلاش کنید",
        variant: "destructive",
      });
    },
  });
};

/**
 * Custom hook to fetch similar products for a given product ID
 */
export const useSimilarProducts = (
  productId: string,
  pageSize: number = 12
) => {
  const apiApi = createApiApi();

  return useQuery({
    queryKey: ["similarProducts", productId, pageSize],
    queryFn: async () => {
      if (!productId) throw new Error("Product ID is required");

      return await apiApi.apiProductV1ProductsSimilarList({
        id: productId,
        pageSize,
      });
    },
    enabled: !!productId,
  });
};

/**
 * Custom hook for infinite similar products loading using cursor-based pagination
 */
export const useSimilarProductsInfinite = (
  productId: string,
  pageSize: number = 20
) => {
  const apiApi = createApiApi();

  return useInfiniteQuery<PaginatedSimilarProduct>({
    queryKey: ["similarProductsInfinite", productId, pageSize],
    queryFn: async ({ pageParam }): Promise<PaginatedSimilarProduct> => {
      if (!productId) throw new Error("Product ID is required");

      // If pageParam is a full URL, extract the cursor
      let cursor: string | undefined = undefined;
      if (typeof pageParam === "string" && pageParam.includes("cursor=")) {
        const url = new URL(pageParam);
        const cursorParam = url.searchParams.get("cursor");
        if (cursorParam) cursor = cursorParam;
      } else if (typeof pageParam === "string") {
        cursor = pageParam;
      }

      return await apiApi.apiProductV1ProductsSimilarList({
        id: productId,
        cursor,
        pageSize,
      });
    },
    getNextPageParam: (lastPage) => {
      return lastPage.next || undefined;
    },
    initialPageParam: undefined,
    enabled: !!productId,
  });
};
