import {
    ApiHandlerDiscreteParameter,
    createHandlerChainRunner,
    HasOnComplete,
} from "@insite/client-framework/HandlerCreator";
import { addCartPromotion, AddCartPromotionApiParameter } 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 Result = {
    successMessage: string;
    errorMessage: string;
    isPromotionAppliedSuccess: boolean;
};

type HandlerType = ApiHandlerDiscreteParameter<
    {
        promotionCode: string;
    } & HasOnComplete<Result>,
    AddCartPromotionApiParameter,
    PromotionModel,
    Result
>;

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

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 current cart when we were trying to apply a promotion to it.");
    }

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

export const AddCartPromotion: HandlerType = async props => {
    const result = await addCartPromotion(props.apiParameter);
    if (result.successful) {
        props.apiResult = result.result;
        props.successMessage = result.result.message;
        props.isPromotionAppliedSuccess = result.successful;
    } else {
        props.errorMessage = result.errorMessage!;
    }
};

export const DispatchCompleteApplyPromotion: HandlerType = props => {
    props.dispatch({
        type: "Pages/CheckoutReviewAndSubmit/CompleteApplyPromotion",
        successMessage: props.successMessage,
        errorMessage: props.errorMessage,
        isPromotionAppliedSuccess: props.isPromotionAppliedSuccess,
    });
};

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 }));
    }
};

/** @deprecated Not needed anymore */
export const LoadPromotions: HandlerType = () => {};

export const chain = [
    DispatchBeginApplyPromotion,
    PopulateApiParameter,
    AddCartPromotion,
    DispatchCompleteApplyPromotion,
    ResetData,
    LoadCart,
    LoadPromotions,
];

const applyPromotion = createHandlerChainRunner(chain, "ApplyPromotion");
export default applyPromotion;
