import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import * as api from "../service/CartService";
import type { CartResponse, CartItem } from "../types/Types";
import type { ProductsResponse } from "@/app/[name]/(Main)/types/Types";
import { getProductEffectivePrice } from "@/app/[name]/(Main)/types/Types";

export const useBulkCart = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: api.bulkCart,
    onSuccess: () => {
      queryClient.refetchQueries({ queryKey: ["cart-items"] });
    },
  });
};

export const useIncrementCart = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: api.increment,
    onMutate: async (id: string | number) => {
      await queryClient.cancelQueries({ queryKey: ["cart-items"] });
      await queryClient.cancelQueries({ queryKey: ["menu"] });

      const previousCart = queryClient.getQueryData<CartResponse>([
        "cart-items",
      ]);
      const productsData = queryClient.getQueryData<ProductsResponse>(["menu"]);

      if (previousCart?.data && productsData?.data) {
        const existingItem = previousCart.data.items.find(
          (item) => item.variantId === String(id)
        );

        let updatedItems: CartItem[];
        let newTotalItems: number;

        if (existingItem) {
          updatedItems = previousCart.data.items.map((item) => {
            if (item.variantId === String(id)) {
              return {
                ...item,
                quantity: item.quantity + 1,
                totalPrice: item.price * (item.quantity + 1) * (1 - item.discount / 100),
              };
            }
            return item;
          });
          newTotalItems = previousCart.data.totalItems + 1;
        } else {
          const variantId = String(id);
          const product = productsData.data.find((p) =>
            p.variants?.some((v) => v.id === variantId)
          );
          const variant = product?.variants?.find((v) => v.id === variantId);
          if (product && variant) {
            const effectivePrice = getProductEffectivePrice(product);
            const price = variant.price ?? effectivePrice;
            const discount = product.discount ?? 0;
            const newItem: CartItem = {
              variantId,
              productTitle: product.title || product.name || "",
              quantity: 1,
              price,
              discount,
              totalPrice: price * (1 - discount / 100),
            };
            updatedItems = [...previousCart.data.items, newItem];
            newTotalItems = previousCart.data.totalItems + 1;
          } else {
            return { previousCart };
          }
        }

        // محاسبه subTotal جدید
        const newSubTotal = updatedItems.reduce(
          (sum, item) => sum + item.totalPrice,
          0
        );

        // محاسبه total جدید (با حفظ deliveryFee، tax و discount)
        const newTotal =
          newSubTotal +
          (previousCart.data.deliveryFee || 0) -
          (previousCart.data.totalDiscount || 0) +
          (previousCart.data.tax || 0);

        queryClient.setQueryData<CartResponse>(["cart-items"], {
          ...previousCart,
          data: {
            ...previousCart.data,
            items: updatedItems,
            totalItems: newTotalItems,
            subTotal: newSubTotal,
            total: newTotal,
          },
        });
      }

      return { previousCart };
    },
    onError: (_err, _id, context) => {
      if (context?.previousCart) {
        queryClient.setQueryData(["cart-items"], context.previousCart);
      }
    },
    onSuccess: () => {
      queryClient.refetchQueries({ queryKey: ["cart-items"] });
    },
  });
};

export const useDecrementCart = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: api.decrement,
    onMutate: async (id: string | number) => {
      await queryClient.cancelQueries({ queryKey: ["cart-items"] });

      const previousCart = queryClient.getQueryData<CartResponse>([
        "cart-items",
      ]);

      if (previousCart?.data) {
        const updatedItems = previousCart.data.items
          .map((item: CartItem) => {
            if (item.variantId === String(id)) {
              const newQuantity = item.quantity - 1;
              if (newQuantity <= 0) {
                return null;
              }
              return {
                ...item,
                quantity: newQuantity,
                totalPrice: item.price * newQuantity * (1 - item.discount / 100),
              };
            }
            return item;
          })
          .filter((item: CartItem | null): item is CartItem => item !== null);

        // محاسبه subTotal جدید
        const newSubTotal = updatedItems.reduce(
          (sum, item) => sum + item.totalPrice,
          0
        );

        // محاسبه total جدید
        const newTotal =
          newSubTotal +
          (previousCart.data.deliveryFee || 0) -
          (previousCart.data.totalDiscount || 0) +
          (previousCart.data.tax || 0);

        queryClient.setQueryData<CartResponse>(["cart-items"], {
          ...previousCart,
          data: {
            ...previousCart.data,
            items: updatedItems,
            totalItems: Math.max(0, previousCart.data.totalItems - 1),
            subTotal: newSubTotal,
            total: newTotal,
          },
        });
      }

      return { previousCart };
    },
    onError: (_err, _id, context) => {
      if (context?.previousCart) {
        queryClient.setQueryData(["cart-items"], context.previousCart);
      }
    },
    onSuccess: () => {
      queryClient.refetchQueries({ queryKey: ["cart-items"] });
    },
  });
};

export const useClearCart = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: api.clear,
    onSuccess: () => {
      queryClient.refetchQueries({ queryKey: ["cart-items"] });
    },
  });
};

export const useGetCartItems = (enabled = true) => {
  return useQuery({
    queryKey: ["cart-items"],
    queryFn: api.getCartItems,
    enabled,
    refetchOnMount: false,
    refetchOnWindowFocus: false,
    refetchOnReconnect: false,
  });
};

export const useSaveAllMethod = () => {
  return useMutation({
    mutationFn: api.saveAllMethod,
  });
};
