"use client";

import { useMutation, useQuery } from "@tanstack/react-query";
import { useCallback, useEffect, useState } from "react";

import { QueryKeys } from "../constants/query-keys";
import { useMainContext } from "../contexts/MainWrapperContext";
import { CartsService } from "../services/api";
import { ShippingMethodsService } from "../services/api";
import { useCartStore } from "../stores/cartStore";
import { countriesStore } from "../stores/countriesStore";
import { withTimeout } from "../utils/app.util";
import { notification } from "../utils/notifications.util";
import { UsaHomeStationErrorCode } from "../utils/usa-home-station-error.constants";
import { useUsaHomeStationErrorMessage } from "./useUsaHomeStationErrorMessage";

function isUsaHomeStationApiError(error: { body?: { code?: string }; code?: string }) {
  const code = error?.body?.code ?? error?.code;
  return (
    code === UsaHomeStationErrorCode.QUOTA_EXCEEDED ||
    code === UsaHomeStationErrorCode.ELIGIBILITY_CHECK_FAILED ||
    code === UsaHomeStationErrorCode.USER_NOT_FOUND
  );
}

export function useCart() {
  const [revalidateCartSuccess, setRevalidateCartSuccess] = useState(false);
  const { triggerInvalidDialog } = useMainContext();
  const { setShippingCountries } = countriesStore();
  const resolveUsaHomeStationError = useUsaHomeStationErrorMessage();

  //
  const { cart, commissionNonEligibleFound, setLoading, setCart } =
    useCartStore();

  const { data: cartData, refetch: getCart } = useQuery({
    queryKey: [QueryKeys.cart.GET_CART],
    queryFn: CartsService.cartsControllerGetCart,
    enabled: true,
  });

  useEffect(() => {
    // Update cart store whenever cartData changes, including when it's null (empty cart)
    if (cartData !== undefined && revalidateCartSuccess) {
      setCart(cartData);
    }
  }, [cartData, setCart, revalidateCartSuccess]);

  const revalidateCart = useCallback(async () => {
    await setRevalidateCartSuccess(false);
    const result = await getCart();
    await setRevalidateCartSuccess(result.status === "success");
  }, [getCart]);

  const addToCart = useMutation({
    mutationKey: [QueryKeys.cart.ADD_TO_CART],
    mutationFn: CartsService.cartsControllerAddCartProduct,
    onMutate: () => setLoading(true),
    onSuccess: () => {
      //
      revalidateCart();
    },
    onError: (error: any) => {
      setLoading(false);
      if (error?.status === 404) {
        triggerInvalidDialog();
        return;
      }
      if (isUsaHomeStationApiError(error)) {
        notification.notifyError(resolveUsaHomeStationError(error));
      }
    },
  });

  const removeProductFromCart = useMutation({
    mutationKey: [QueryKeys.cart.REMOVE_FROM_CART],
    mutationFn: CartsService.cartsControllerRemoveCartProduct,
    onMutate: () => setLoading(true),
    onSuccess: () => {
      revalidateCart();
    },
    onError: () => setLoading(false),
  });

  const removeProductsFromCart = useMutation({
    mutationKey: [QueryKeys.cart.REMOVE_PRODUCT_FROM_CART],
    mutationFn: CartsService.cartsControllerDeleteCartProducts,
    onMutate: () => setLoading(true),
    onSuccess: () => {
      revalidateCart();
    },
    onError: () => setLoading(false),
  });

  const updateCartState = useMutation({
    mutationKey: [QueryKeys.cart.UPDATE_CART_STATE],
    mutationFn: CartsService.cartsControllerUpdateCartState,
    onMutate: () => setLoading(true),
    onSuccess: async () => {
      revalidateCart();
    },
    onError: (error: any) => {
      setLoading(false);
      if (isUsaHomeStationApiError(error)) {
        notification.notifyError(resolveUsaHomeStationError(error));
      }
    },
  });

  const updateCartAddresses = useMutation({
    mutationKey: [QueryKeys.cart.UPDATE_ADDRESSES],
    mutationFn: CartsService.cartsControllerUpdateAddresses,
    onMutate: () => setLoading(true),
    onSuccess: () => revalidateCart(),
    onError: (error: any) => {
      setLoading(false);
      if (isUsaHomeStationApiError(error)) {
        notification.notifyError(resolveUsaHomeStationError(error));
      }
    },
  });

  //#TODO Update with the Update shipping address API
  const updateCartShippingAddresses = useMutation({
    mutationKey: [QueryKeys.cart.UPDATE_SHIPPING_ADDRESSES],
    mutationFn: CartsService.cartsControllerShippingAddresses,
    onMutate: () => setLoading(true),
    onSuccess: () => revalidateCart(),
    onError: (error: any) => {
      setLoading(false);
      if (isUsaHomeStationApiError(error)) {
        notification.notifyError(resolveUsaHomeStationError(error));
      }
    },
  });

  const updatePaymentMethod = useMutation({
    mutationKey: [QueryKeys.cart.UPDATE_PAYMENT_METHOD],
    mutationFn: (params: {
      paymentMethodId: number;
      paymentOptionId: number;
      fromAssetSelectedPercentage: number;
      optionAssetSymbol?: string;
      optionAssetName?: string;
      payCurrencyCode?: string;
      nowpaymentsCurrencyId?: number;
    }) => {
      if (
        process.env.NODE_ENV === "development" ||
        process.env.NEXT_PUBLIC_DEBUG_PAYMENT_FLOW === "1"
      ) {
        console.info(
          "[H-Mall Payment][useCart.updatePaymentMethod] request",
          params,
        );
      }
      return CartsService.cartsControllerUpdatePaymentMethod(params);
    },
    onMutate: () => setLoading(true),
    onSuccess: () => revalidateCart(),
    onError: () => setLoading(false),
  });

  const deleteCart = useMutation({
    mutationKey: [QueryKeys.cart.DELETE_CART],
    mutationFn: CartsService.cartsControllerDeleteCart,
    onMutate: () => setLoading(true),
    onSuccess: () => {
      revalidateCart();
    },
    onError: () => setLoading(false),
  });

  const refreshCart = useMutation({
    mutationKey: [QueryKeys.cart.REFRESH_CART],
    mutationFn: async (mode: string) => {
      try {
        await CartsService.cartsControllerValidateCart(mode);
        return true;
      } catch (error) {
        console.log("🚀 ~ useCart ~ error:", error);
        return false;
      }
    },
    onMutate: () => setLoading(true),
    onSuccess: () => revalidateCart(),
    onError: () => setLoading(false),
  });

  const getShippingMethods = useMutation({
    mutationKey: [QueryKeys.shippingCart.GET_SHIPPING_METHODS],
    //#TODO Update with the Get shipping methods API for the new cart flow
    mutationFn: () => ShippingMethodsService.shippingMethodControllerFindAll(),
    onSuccess: async () => {},
    onError: () => setLoading(false),
  });

  const getCountriesByShippingMethodId = useMutation({
    mutationKey: [QueryKeys.upgradeCart.GET_COUNTRIES_BY_SHIPPING_METHOD],
    retry: 5,
    retryDelay: 1000,
    mutationFn: ({ shippingMethodId }: { shippingMethodId: number }) =>
      // proceedGetShippingCountriesAsync(shippingMethodId),
      withTimeout(
        CartsService.getCountriesByShippingMethod(shippingMethodId),
        3000, // 3 seconds timeout
      ),

    onSuccess: (data: any) => {
      setShippingCountries(data);
    },
    onError: (error: any) => {
      console.log("🚀 ~ useMigrationCart ~ error:", error);
    },
  });

  const resetCartAddress = useMutation({
    mutationKey: [QueryKeys.cart.RESET_CART_ADDRESS],
    mutationFn: (type: string) => CartsService.resetCartAddresses(type),
    onMutate: () => setLoading(true),
    onSuccess: async () => {
      revalidateCart();
    },

    onError: () => setLoading(false),
  });

  return {
    cart,
    getCart,
    addToCart,
    deleteCart,
    updateCartState,
    // deleteFromCart,
    updateCartAddresses: updateCartAddresses,
    updateCartShippingAddresses: updateCartShippingAddresses,
    resetCartAddress: resetCartAddress,
    updatePaymentMethod,
    removeProductFromCart,
    commissionNonEligibleFound,
    removeProductsFromCart,
    refreshCart,
    getShippingMethods,
    getCountriesByShippingMethodId,
  };
}
