import {
    ApiHandlerDiscreteParameter,
    createHandlerChainRunnerOptionalParameter,
} from "@insite/client-framework/HandlerCreator";
import { removeCartPromotions, RemoveCartPromotionsApiParameter } from "@insite/client-framework/Services/CartService";
import { getCartState, getCurrentCartState } from "@insite/client-framework/Store/Data/Carts/CartsSelector";
import loadCart from "@insite/client-framework/Store/Data/Carts/Handlers/LoadCart";
import loadCurrentCart from "@insite/client-framework/Store/Data/Carts/Handlers/LoadCurrentCart";
import { getQueryStrings } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import { PromotionModel } from "@insite/client-framework/Types/ApiModels";

type HandlerType = ApiHandlerDiscreteParameter<
    {},
    RemoveCartPromotionsApiParameter,
    PromotionModel,
    {
        successMessage: string;
        errorMessage: string;
        isPromotionsRemovedSuccess: boolean;
    }
>;

export const DispatchBeginRemovePromotions: HandlerType = props => {
    props.dispatch({
        type: "Pages/CheckoutReviewAndSubmit/BeginRemovePromotions",
    });
};

export const PopulateApiParameter: HandlerType = props => {
    const state = props.getState();
    const { cartId } = getQueryStrings(state);
    const cart = cartId ? getCartState(state, cartId).value : getCurrentCartState(state).value;
    if (!cart) {
        throw new Error("There was no cart when we were trying to remove a promotion from it.");
    }

    props.apiParameter = {
        cartId: cart.id,
    };
};

export const RemoveCartPromotions: HandlerType = async props => {
    const result = await removeCartPromotions(props.apiParameter);
    if (result.successful) {
        props.successMessage = props.apiParameter.cartId;
        props.isPromotionsRemovedSuccess = result.successful;
    } else {
        props.errorMessage = result.errorMessage!;
    }
};

export const DispatchCompleteRemovePromotions: HandlerType = props => {
    props.dispatch({
        type: "Pages/CheckoutReviewAndSubmit/CompleteRemovePromotions",
        successMessage: props.successMessage,
        errorMessage: props.errorMessage,
        isPromotionsRemovedSuccess: props.isPromotionsRemovedSuccess,
    });
};

export const ResetData: HandlerType = props => {
    props.dispatch({
        type: "Data/Promotions/Reset",
    });
};

export const LoadCart: HandlerType = props => {
    const state = props.getState();
    const { cartId } = getQueryStrings(state);
    if (cartId) {
        props.dispatch(loadCart({ cartId, getPromotions: true }));
    } else {
        props.dispatch(loadCurrentCart({ getPromotions: true }));
    }
};

export const chain = [
    DispatchBeginRemovePromotions,
    PopulateApiParameter,
    RemoveCartPromotions,
    DispatchCompleteRemovePromotions,
    ResetData,
    LoadCart,
];

const removePromotions = createHandlerChainRunnerOptionalParameter(chain, {}, "RemovePromotions");
export default removePromotions;
