import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import * as api from "../service/CartService";
import type { CartResponse, CartItem } from "../types/Types";
import type { FoodsResponse } 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 foodsData = queryClient.getQueryData<FoodsResponse>(["menu"]);

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

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

        if (existingItem) {
          updatedItems = previousCart.data.items.map((item) => {
            if (item.foodId === 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 food = foodsData.data.find((f) => String(f.id) === String(id));
          if (food) {
            const newItem: CartItem = {
              foodId: String(id),
              foodTitle: food.title,
              quantity: 1,
              price: food.price,
              discount: food.discount || 0,
              totalPrice: food.price * (1 - (food.discount || 0) / 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.foodId === 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,
    staleTime: 60_000,
    refetchOnMount: false,
    refetchOnWindowFocus: false,
    refetchOnReconnect: false,
  });
};

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