<template>
    <div>
        <textLink
            id="promoLinkPromptId"
            linkType="text"
            :text="promoLinkText"
            href="#!"
            @click-event="openModal" />
        <modal
            :ref="modalName"
            :headerText="modalHeaderText"
            :onModalClosedCallback="onModalClosed"
            :footerButtonText="modalFooterText"
            @footer-button-event="addPromoCode">
            <promoQuestion
                ref="promoQuestion"
                customInputId="promoCode"
                v-model="promoCode"
                cmsWidgetName="PromoQuestionWidget" />
            <alert
                ref="alertInvalidPromo"
                v-if="displayInvalidPromoAlert"
                v-html="InvalidPromoText"
                class="my-4 alert"
                cmsWidgetName="AlertInvalidPromoWidget"
                alertClass="alert-danger"
                v-bind:isDismissible="true" />
            <alert
                ref="alertInvalidPromoOnOrder"
                v-if="displayInvalidOnOrderPromoAlert"
                v-html="InvalidPromoOnOrderText"
                class="my-4 alert"
                cmsWidgetName="AlertInvalidPromoOnOrderWidget"
                alertClass="alert-danger"
                v-bind:isDismissible="true" />
            <div v-for="(promo, i) in this.getPromoList()" :key="i">
                <span class="applied-promo">Promo code "{{ promo.promoCode }}" applied </span>
                <textLink
                    ref="removeLink"
                    linkType="text"
                    :text="removeLinkText"
                    href="#!"
                    @click-event="removeItem(promo.promoCode)" />
            </div>
        </modal>
    </div>
</template>
<script>
import textLink from "@/ux-components/text-link/text-link";
import promoQuestion from "@/layouts/payment-method/promo-modal-question/promo-question/promo-question";
import modal from "@/digital-components/modal/modal";
import alert from "@/ux-components/alert/alert";
import { storeActions } from "@/constants/store-actions.js";
import {
    getVapsThatNeedToBeAddedToSatisfyPromos,
    promoErrorCodes,
} from "@/helpers/promotions-helper";
import { deepClone } from "@/helpers/object-helper";
import baseMixin from "@/mixins/base-mixin.js";
import { cartItemCategories } from "@/constants/cart-item-categories";
import store from "@/store";
import { mapTaxedLineItemsToStoreFormat } from "@/store";
export default {
    name: "promo-modal-question",

    data() {
        return {
            promoCode: "",
            promoTextInputId: "",
            displayInvalidPromoAlert: false,
            displayInvalidOnOrderPromoAlert: false,
            lineItems: deepClone(this.modelValue),
        };
    },
    props: {
        modelValue: Object,
        linkWidgetName: String,
        modalWidgetName: String,
        availableVaps: Object,
    },
    computed: {
        promoLinkText() {
            return this.getCmsContent(this.linkWidgetName, "BodyText");
        },
        modalHeaderText() {
            return this.getCmsContent("PromoQuestionWidget", "QuestionText");
        },
        modalFooterText() {
            return this.getCmsContent(this.modalWidgetName, "FooterText");
        },
        modalName() {
            return this.modalWidgetName;
        },
        modal() {
            return this.$refs[this.modalName];
        },
        PromoOnOrderText() {
            return this.getCmsContent("AlertInvalidPromoOnOrderWidget", "HeadlineText");
        },
        InvalidPromoOnOrderText() {
            return this.PromoOnOrderText?.replaceAll(
                "{custom:NEWPROMOCODE}",
                this.promoCode.toUpperCase()
            ).replaceAll("{custom:OLDPROMOCODE}", this.getPromoCode().toUpperCase());
        },
        PromoText() {
            return this.getCmsContent("AlertInvalidPromoWidget", "HeadlineText");
        },
        InvalidPromoText() {
            return this.PromoText?.replaceAll("{custom:PROMOCODE}", this.promoCode.toUpperCase());
        },
        removeLinkText() {
            return this.getCmsContent("RemoveCartItemTextWidget", "Text");
        },
    },
    methods: {
        resetAlerts() {
            this.displayInvalidOnOrderPromoAlert = false;
            this.displayInvalidPromoAlert = false;
        },
        resetsOnPromoInput() {
            this.resetAlerts();
        },
        getPromoList() {
            return this.lineItems.promos;
        },
        getPromoCode() {
            return this.lineItems.promos?.[0].promoCode;
        },
        openModal() {
            this.modal.openModal();
        },
        closeModal() {
            this.modal.closeModal();
        },
        onModalClosed() {
            this.resetAlerts();
            this.$emit("update:modelValue", this.lineItems);
            this.promoCode = "";
        },
        focusOnPromoInput() {
            const input = document.getElementById(this.promoTextInputId);
            input?.focus();
        },
        resetModalButtonStyle() {
            this.modal.resetButtonStyle();
        },
        async getPromoCodeData(promoCode, lineItems, availableVaps, pageNameToLog = null) {
            const pageName = pageNameToLog ?? this.$options?.name;
            const promoValidationResponse = await baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA,
                {
                    promoCode: promoCode,
                    lineItemsToUse: lineItems,
                    addableVaps: availableVaps,
                },
                pageName,
                false
            );

            return {
                isValid: !("errorCode" in promoValidationResponse),
                promoCode: promoValidationResponse?.orderPromos,
                errorCode: promoValidationResponse?.errorCode,
            };
        },
        removeItem(promo) {
            this.lineItems[cartItemCategories.PROMOS] = this.lineItems[
                cartItemCategories.PROMOS
            ].filter((lineItemsToKeep) => lineItemsToKeep.promoCode != promo);
        },
        async addPromoCode() {
            if (this.promoCode) {
                this.resetAlerts();

                const promoCodeData = await this.getPromoCodeData(
                    this.promoCode,
                    this.lineItems,
                    this.availableVaps,
                    "payment-method"
                );

                if (promoCodeData.isValid) {
                    const pricedLineItemsToTax = [];
                    pricedLineItemsToTax.push(...promoCodeData.promoCode);
                    const taxedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
                        storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
                        {
                            billToAccountNumber: "87291",
                            providerNumber:
                                store.getters.order.serviceLocation.provider.providerNumber,
                            appointmentType: store.getters.order.serviceLocation.appointmentType,
                            serviceLocationCity: store.getters.order.serviceLocation.city,
                            serviceLocationState: store.getters.order.serviceLocation.state,
                            serviceLocationZipCode: store.getters.order.serviceLocation.zipCode,
                            pricedLineItems: pricedLineItemsToTax,
                        },
                        "payment-method",
                        false
                    );
                    // Match all line items to the line items as they are in the store
                    // and rebuild the original structure.
                    this.lineItems = mapTaxedLineItemsToStoreFormat(taxedLineItems, this.lineItems);
                    const taxedVaps = mapTaxedLineItemsToStoreFormat(
                        taxedLineItems,
                        this.availableVaps
                    );

                    const getVaps = getVapsThatNeedToBeAddedToSatisfyPromos(
                        promoCodeData.promoCode,
                        taxedVaps,
                        this.lineItems
                    );
                    this.lineItems?.promos.push(...promoCodeData.promoCode);
                    this.lineItems.vaps?.push(...getVaps);
                    this.closeModal();
                } else {
                    if (promoCodeData.errorCode == promoErrorCodes.PROMO_STACKING_NOT_ALLOWED) {
                        this.displayInvalidOnOrderPromoAlert = true;
                    } else {
                        this.displayInvalidPromoAlert = true;
                    }
                    this.focusOnPromoInput();
                    this.resetModalButtonStyle();
                }
            }
        },
    },
    watch: {
        promoCode() {
            this.displayInvalidPromoAlert = false;
            this.displayInvalidOnOrderPromoAlert = false;
        },
        modelValue: {
            handler(newValue) {
                this.lineItems = deepClone(newValue);
            },
            deep: true,
        },
    },

    components: {
        textLink,
        promoQuestion,
        modal,
        alert,
    },
};
</script>
<style lang="scss" scoped>
.applied-promo {
    padding-right: 4rem;
    font-size: 14px;
    font-weight: 500;
    line-height: 24px;
    color: #0c7e47;
}
.alert {
    color: #d4281c;
    font-size: 14px;
    font-weight: 500;
    line-height: 24px;
}
</style>
