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

import { ADDRESS_TYPES } from "../constants/app";
import { QueryKeys } from "../constants/query-keys";
import {
  proceedGetCitiesAsync,
  proceedGetStatesAsync,
} from "../services/addresses.service";
import {
  AddressesService,
  StoresService,
  UpdateUserAddressDto,
} from "../services/api";
import { useCartStore } from "../stores/cartStore";
import { countriesStore } from "../stores/countriesStore";
import { notification } from "../utils/notifications.util";
import { useShippingAddressForm } from "./useShippingAddressForm";

export function useAddressForm() {
  //
  const {
    setStates,
    setShippingStates,
    setCities,
    setShippingCities,
    setLoading,
    setLoadingCities,
    setShippingLoadingCities,
    setStores,
  } = countriesStore();
  const { userBillingAddress, setUserBillingAddress } = useCartStore();

  const { getShippingAddress } = useShippingAddressForm();

  const getCityByStateAndCountry = useMutation({
    mutationKey: [QueryKeys.users.GET_SHIPPING_STATE_BY_COUNTRY],
    mutationFn: ({
      countryId,
      stateId,
    }: {
      countryId: number;
      stateId?: number;
    }) => proceedGetCitiesAsync(countryId, stateId),
    onSuccess: (data) => {
      setCities(data);
      setLoadingCities(false);
    },
    onError: () => {},
  });
  const getShippingCityByStateAndCountry = useMutation({
    mutationKey: [QueryKeys.users.GET_SHIPPING_CITY_BY_STATE_AND_COUNTRY],
    mutationFn: ({
      countryId,
      stateId,
    }: {
      countryId: number;
      stateId?: number;
    }) => proceedGetCitiesAsync(countryId, stateId),
    onSuccess: (data) => {
      setShippingCities(data);
      setShippingLoadingCities(false);
    },
    onError: () => {},
  });

  const getStatesByCountry = useMutation({
    mutationKey: [QueryKeys.users.GET_STATE_BY_COUNTRY],
    mutationFn: proceedGetStatesAsync,
    onSuccess: async (data: any[]) => {
      setStates(data);
      setLoading(false);
    },
    onError: () => {},
  });
  const getShippingStatesByCountry = useMutation({
    mutationKey: [QueryKeys.users.GET_SHIPPING_STATE_BY_COUNTRY],
    mutationFn: proceedGetStatesAsync,
    onSuccess: async (data: any[]) => {
      setShippingStates(data);
      setLoading(false);
    },
    onError: () => {},
  });

  const getStoreByCountry = useMutation({
    mutationKey: [QueryKeys.users.GET_STORE_BY_COUNTRY],
    mutationFn: StoresService.storesControllerFindAll,
    onSuccess: async (data: any[]) => {
      setStores(data);
      setLoading(false);
    },
    onError: () => {},
  });

  const addNewAddress = useMutation({
    mutationKey: [QueryKeys.users.ADD_NEW_ADDRESS],
    mutationFn: AddressesService.userAddressesControllerAddNewAddress,
    onSuccess: () => {
      setStates([]);
      setShippingStates([]);
      setCities([]);
      setShippingCities([]);
      getAddress();
    },
    onError: () => {},
  });

  const updateAddress = useMutation({
    mutationKey: [QueryKeys.users.UPDATE_ADDRESS],
    mutationFn: ({
      id,
      requestBody,
    }: {
      id: number;
      requestBody: UpdateUserAddressDto;
    }) =>
      AddressesService.userAddressesControllerUpdateAddress(id, requestBody),
    onSuccess: () => {
      notification.notifySuccess("Your address has been updated successfully");
      getAddress();
      getShippingAddress();
    },
    onError: () => {},
  });

  const deleteAddress = useMutation({
    mutationKey: [QueryKeys.users.DELETE_ADDRESS],
    mutationFn: ({ id }: { id: number }) =>
      AddressesService.userAddressesControllerDeleteAddress(id),
    onSuccess: () => {
      notification.notifySuccess("Your address has been deleted successfully");
      getAddress();
      getShippingAddress();
    },
    onError: () => {},
  });

  const {
    data: userBilling,
    isLoading: isLoadingAddresses,
    refetch: getAddress,
  } = useQuery({
    queryKey: [QueryKeys.users.GET_ADDRESSES],
    queryFn: () =>
      AddressesService.userAddressesControllerGetAllActiveUserAddresses(
        ADDRESS_TYPES.billing.value,
      ),
    enabled: !userBillingAddress,
  });

  useEffect(() => {
    setUserBillingAddress(userBilling);
  }, [userBilling, setUserBillingAddress]);

  return {
    getStatesByCountry,
    getShippingStatesByCountry,
    getStoreByCountry,
    getCityByStateAndCountry,
    getShippingCityByStateAndCountry,
    addNewAddress,
    updateAddress,
    deleteAddress,
    billingAddress: userBillingAddress,
    isLoadingAddresses,
    getAddress,
  };
}
