import {
    ApiHandlerDiscreteParameter,
    createHandlerChainRunner,
    HasOnComplete,
} from "@insite/client-framework/HandlerCreator";
import { removeCartPromotion, RemoveCartPromotionApiParameter } 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<
    {
        promotionId: string;
    } & HasOnComplete<void>,
    RemoveCartPromotionApiParameter,
    PromotionModel,
    {
        successMessage: string;
        errorMessage: string;
        isPromotionRemovedSuccess: boolean;
    }
>;

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

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,
        promotionId: props.parameter.promotionId,
    };
};

export const RemoveCartPromotion: HandlerType = async props => {
    const result = await removeCartPromotion(props.apiParameter);
    if (result.successful) {
        props.successMessage = props.apiParameter.promotionId;
        props.isPromotionRemovedSuccess = result.successful;
    } else {
        props.errorMessage = result.errorMessage!;
    }
};

export const DispatchCompleteRemovePromotion: HandlerType = props => {
    props.dispatch({
        type: "Pages/CheckoutReviewAndSubmit/CompleteRemovePromotion",
        successMessage: props.successMessage,
        errorMessage: props.errorMessage,
        isPromotionRemovedSuccess: props.isPromotionRemovedSuccess,
    });
};

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 = [
    DispatchBeginRemovePromotion,
    PopulateApiParameter,
    RemoveCartPromotion,
    DispatchCompleteRemovePromotion,
    ResetData,
    LoadCart,
];

const removePromotion = createHandlerChainRunner(chain, "RemovePromotion");
export default removePromotion;
