<template>
    <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
        <loadingModal notFullScreen ref="loadingModal" />
        <funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
        <div class="container payment-method">
            <div class="row">
                <div class="col-12 col-md-10 col-lg-8 col-xl-7">
                    <funnelSubHeader class="mb-5" cmsWidgetName="FunnelSubHeaderWidget" alignLeft />

                    <hr class="my-0" />

                    <reviewDropdown
                        class="appt-details-snapshot"
                        ref="reviewDropdown"
                        :apptWordingText="AppointmentWordingText" />

                    <hr class="my-0" />

                    <cart
                        ref="cart"
                        :damage="damageInfo"
                        :availableVaps="availableVaps"
                        :allowItemRemoval="true"
                        v-model="lineItems"
                        v-model:inactivePromos="inactivePromos"
                        pageName="payment-method"
                        servicePackageOptionsCmsName="ServicePackageTitle"
                        recyclingModalCmsWidgetName="RecycleModal"
                        :isInsurance="isInsurance"
                        :insuranceDeductible="currentDeductible"
                        :insuranceCompanyName="insuranceCompanyName"
                        :showInsuranceCoverageAs="showInsuranceCoverageAs"
                        :shouldHideRecalibration="shouldHideRecalibration"
                        :isItac="isItac"
                        :isNoComp="isNoComp"
                        :isExpandedOnLoad="false"
                        :isMSRFeeApplicable="isMSRFeeApplicable"
                        @itemRemoved="evaluatePromosAndTaxItemsOnOrder" />

                    <afterpayBreakout
                        v-if="isAfterpayBreakoutDisplay"
                        cmsWidgetName="AfterpayBreakoutAlertWidget"
                        :totalAmount="totalAmountDue" />
                    <hr />

                    <div>
                        <alert
                            ref="piaErrorAlert"
                            class="my-4"
                            v-if="shouldDisplayPiaAlert"
                            cmsWidgetName="PIAErrorAlertWidget"
                            alertClass="alert-danger"
                            v-bind:isDismissible="false" />
                    </div>

                    <div
                        v-if="isRecalibrationOnOrder && shouldHideRecalibration"
                        class="questions-about-service mt-5">
                        <textBlock
                            cmsWidgetName="QuestionsAboutYourServiceWidget"
                            justifyText="left"
                            class="service-questions" />
                        <textBlock cmsWidgetName="CallOrTextWidget" justifyText="left" />
                        <hr class="my-5" />
                        <div class="d-flex flex-column checkbox-group">
                            <Field
                                name="recalAckOptIn"
                                :rules="'recal-ack-required'"
                                v-model="isRecalAckOptIn"
                                v-slot="{ meta, errors }">
                                <checkboxQuestion
                                    cmsWidgetName="RecalConfirmWidget"
                                    class="mb-3"
                                    isRequired="true"
                                    v-model="isRecalAckOptIn"
                                    validationRules="recal-ack-required"
                                    checkboxName="recalAckOptIn"
                                    :class="{ 'is-invalid': meta.touched && errors.length > 0 }"
                                    @text-link-clicked="openModal('RecalModal')" />
                            </Field>
                            <div id="form-test-error" class="row form-test-error">
                                <error-message
                                    role="comment"
                                    aria-atomic="true"
                                    aria-live="polite"
                                    class="small mt-1 text-danger d-block"
                                    :name="'recalAckOptIn'"></error-message>
                            </div>
                        </div>
                    </div>

                    <paymentMethodQuestion
                        v-if="showPaymentMethodQuestions"
                        v-model="paymentMethodInternalModel"
                        :showApplePay="showApplePay"
                        :isInsurance="isInsurance"
                        validationRules="payment-method-required" />

                    <navbar
                        cmsWidgetName="FunnelFooterWidget"
                        ref="navbar"
                        :isForwardActionDisabled="!meta.valid"
                        :isBackButtonHidden="shouldHideBackButton"
                        buttonSize
                        @back-clicked="backButtonAction"
                        @ForwardClicked="forwardButtonAction" />

                    <contentGroupModal
                        ref="RecalModal"
                        cmsWidgetName="RecalModal"
                        class="recal-modal"
                        isRecal />
                </div>
            </div>
        </div>
    </Form>
</template>

<script>
// Components
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import navbar from "@/fmg-components/nav-bar/nav-bar";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import paymentMethodQuestion from "@/layouts/payment-method/payment-method-question/payment-method-question";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import cart from "@/fmg-components/cart/cart";
import reviewDropdown from "@/layouts/payment-method/review-dropdown/review-dropdown";
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
import alert from "@/ux-components/alert/alert";
import textBlock from "@/digital-components/text-block/text-block";
import checkboxQuestion from "@/digital-components/checkbox-question/checkbox-question";
import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal";
import afterpayBreakout from "@/layouts/payment-method/afterpay-breakout/afterpay-breakout";

// Supporting Items
import baseMixin from "@/mixins/base-mixin.js";
import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import {
    fetchCmsContentForPage,
    doesCopyContainRouterLink,
    getRouterLinkRouteFromCopy,
} from "@/helpers/cms-content-helper";
import { paymentMethods } from "@/constants/payment-method-constants";
import { experimentSettings } from "@/constants/experiments";
import {
    revalidatePromosAndValidateQueryStringPromo,
    buildToastMessagesFromRevalidateOrValidatePromoResponse,
    getVapsThatNeedToBeAddedToSatisfyPromos,
    getPromoCodeWithoutBundleIdentifier,
    removeCurrentlyActivePromoCodesFromInactivePromos,
    createPromoSuccessAlert,
    createPromoErrorAlert,
    getNewlyInactivatedPromos,
} from "@/helpers/promotions-helper";
import { queryStrings } from "@/constants/query-strings";
import { deepClone } from "@/helpers/object-helper";

import { Form } from "vee-validate";
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
import { coverageStatus } from "@/constants/insurance";
import { containsRecalParts } from "@/helpers/recal-helper";
import { getBoolFromString } from "@/helpers/boolean-helper";
import { getAmountDue, addPricesToLineItems } from "@/helpers/pricing-helper.js";
import { consumeQueryFromStash } from "@/router/methods/helpers/querystring-stash";
import { debugLog } from "@/helpers/debug-log-helper";
import { ErrorMessage } from "vee-validate";
import { Field } from "vee-validate";

defineRule("payment-method-required", required(errorMessages.OPTION_REQUIRED));
defineRule("recal-ack-required", required(errorMessages.RECAL_ACK_REQUIRED));

function getFlattenedArrayOfLineItemsWithChildParts(lineItems, childPartRecursiveCall = false) {
    let flattenedArray = [];
    lineItems?.forEach((lineItem) => {
        // this assumes childparts will never be a glass part
        lineItem.isChildPart = childPartRecursiveCall;
        flattenedArray.push(lineItem);
        if (lineItem.childParts) {
            flattenedArray = [
                ...flattenedArray,
                ...getFlattenedArrayOfLineItemsWithChildParts(lineItem.childParts, true),
            ];
        }
    });

    return flattenedArray;
}

export default {
    name: "paymentMethod",
    props: {
        recyclingModalCmsWidgetName: String,
    },
    async beforeRouteEnter(to, from, next) {
        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to.name);

        const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.GET_WIPERS,
            {
                serviceZipCode: store.getters.order.serviceLocation.zipCode,
                carId: store.getters.vehicle.carId,
            },
            "payment-method"
        );

        const rainRepelPromise = baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.GET_RAIN_REPEL,
            null,
            "payment-method"
        );

        const promiseResultMap = [
            {
                resultKey: "cmsContent",
                promise: cmsContentPromise,
            },
            {
                resultKey: "wipers",
                promise: wipersPromise,
            },
            {
                resultKey: "rainRepel",
                promise: rainRepelPromise,
            },
        ];

        const resultMap = await settleAllPromises(promiseResultMap);

        let lineItemsFromStore = deepClone(store.getters.order.lineItems);
        const glassParts = lineItemsFromStore.glassParts ?? [];
        const supportingItems = lineItemsFromStore.supportingItems ?? [];
        const vaps = lineItemsFromStore.vaps ?? [];

        const availableVaps = [resultMap.rainRepel, ...resultMap.wipers];

        const lineItemsOnOrderAndAvailableVaps = [
            ...availableVaps,
            ...glassParts,
            ...supportingItems,
            ...vaps,
        ];

        // All line items are already priced except availableVaps
        // Price everything again to ensure that serverData has all values
        // Specifically this addresses an error where insurance client glass parts are not in serverData
        // See CASH-1713 for details
        let pricedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
            {
                availableLineItems: lineItemsOnOrderAndAvailableVaps,
            },
            "payment-method",
            false
        );
        pricedLineItems = getFlattenedArrayOfLineItemsWithChildParts(pricedLineItems);

        // Add prices to the availableVaps
        const pricedAvailableVaps = addPricesToLineItems(availableVaps, pricedLineItems);

        // Promo logic
        // Populate the previous state of promos for toast message usage in "next()"
        const oldActivePromos = store.getters.lineItems.promos?.slice(0);
        const oldInactivePromos = store.getters.order.payment.inactivePromos?.slice(0);

        const promoCodeFromQueryString = consumeQueryFromStash(queryStrings.PROMO);
        // New promos are saved to store with this
        const { validatePromoResponse, revalidatePromoResponse } =
            await revalidatePromosAndValidateQueryStringPromo(
                promoCodeFromQueryString,
                lineItemsOnOrderAndAvailableVaps,
                "payment-method"
            );
        // update lineItemsFromStore with newly added promos
        let lineItemsForCart = deepClone(store.getters.order.lineItems);
        delete lineItemsForCart.serverData;

        // End of promo logic

        const vapsToAddToCart = getVapsThatNeedToBeAddedToSatisfyPromos(
            lineItemsForCart.promos ?? [],
            availableVaps,
            lineItemsForCart
        );
        // Add prices to all line items, sometimes they are not there when they come back from heritage
        // See CASH-1713 for details
        lineItemsForCart.glassParts = addPricesToLineItems(
            lineItemsForCart.glassParts ?? [],
            pricedLineItems
        );
        lineItemsForCart.supportingItems = addPricesToLineItems(
            lineItemsForCart.supportingItems ?? [],
            pricedLineItems
        );
        lineItemsForCart.vaps = addPricesToLineItems(lineItemsForCart.vaps ?? [], pricedLineItems);
        lineItemsForCart.vaps.push(...vapsToAddToCart);
        // Tax items on order
        lineItemsForCart = await baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
            {
                billToAccountNumber: store.getters.payment.billToAccountNumber,
                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: lineItemsForCart,
            },
            "payment-method",
            false
        );

        // Call the "next" function to complete the transition to this page.
        next((vm) => {
            vm.setCmsContent(resultMap.cmsContent);
            vm.availableVaps = pricedAvailableVaps;
            vm.lineItems = lineItemsForCart;
            vm.inactivePromos = removeCurrentlyActivePromoCodesFromInactivePromos(
                vm.lineItems.promos,
                vm.inactivePromos
            );
            vm.updateFooterButtonText(vm.customCtaCopy);

            // vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData);
            // (removed temporarily for Heritage parity effort)

            if (revalidatePromoResponse) {
                const revalidateAlerts = buildToastMessagesFromRevalidateOrValidatePromoResponse(
                    revalidatePromoResponse,
                    oldActivePromos,
                    oldInactivePromos
                );

                revalidateAlerts.forEach((alert) => {
                    vm.$refs.funnelHeader.pushGlobalAlert(alert, alert.shouldAutoFade);
                });
            }
            if (validatePromoResponse) {
                const validateAlerts =
                    buildToastMessagesFromRevalidateOrValidatePromoResponse(validatePromoResponse);
                vm.$refs.funnelHeader.pushGlobalAlert(
                    validateAlerts[0],
                    validateAlerts[0].shouldAutoFade
                );
            }
        });
    },
    data() {
        return {
            lineItems: [],
            availableVaps: [],
            paymentMethodInternalModel: this.getPaymentMethodFromStore(),
            inactivePromos: this.getInactivePromosFromStore(),
            isRecalAckOptIn: this.getIsRecalAckOptInFromStore(),
            forwardClicked: false, // this prevents the pia disclaimer from showing when switching to insurance and nav forward
        };
    },
    methods: {
        doesCopyContainRouterLink,
        getRouterLinkRouteFromCopy,
        navigateWithScenario(scenarioName) {
            this.$router.navigateWithoutSaving(scenarioName, this.pageName);
        },
        arePagePrerequisitesValid() {
            // Service Location
            const serviceLocation = store.getters.order.serviceLocation;
            const mobileReqs = !!(
                serviceLocation.address &&
                serviceLocation.city &&
                serviceLocation.state &&
                serviceLocation.zipCode
            );

            const providerLocation = serviceLocation.provider.address;
            const dropOffInshopReqs = !!(
                providerLocation.streetAddress &&
                providerLocation.city &&
                providerLocation.state &&
                providerLocation.zipCode
            );

            const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;

            const serviceLocationReqs =
                (isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);

            // Insurance
            const isInsurance = store.getters.order.payment.isInsurance;
            const insuranceCoverageStatus = store.getters.payment.insuranceCoverage.coverageStatus;
            const currentDeductible = store.getters.policy.currentDeductible;
            const isInsuranceSet = () => {
                if (isInsurance !== null) {
                    if (
                        insuranceCoverageStatus === coverageStatus.VERIFIED &&
                        !(currentDeductible === 0 || currentDeductible > 0)
                    ) {
                        return false; // if coverageStatus is verified there must be a valid deductible also
                    }
                    return true;
                }
                return false;
            };

            // Schedule
            const schedule = store.getters.order.schedule;
            const scheduleReqs = !!(
                schedule.date &&
                schedule.startTime &&
                schedule.endTime &&
                schedule.jobMaxMinutes &&
                schedule.jobMinMinutes
            );

            // Customer
            const customer = store.getters.order.customer;
            const customerReqs = !!(
                customer.firstName &&
                customer.lastName &&
                customer.phoneNumber &&
                customer.emailAddress
            );

            const preReqResult =
                serviceLocationReqs && isInsuranceSet() && scheduleReqs && customerReqs;

            // prettier-ignore
            {
                debugLog("--- payment-method.vue pagePrereqs start ---", null, !preReqResult);
                debugLog("serviceLocationRequs::isMobile:", isMobile, !preReqResult);
                debugLog("serviceLocationReqs::mobileReqs:", mobileReqs, !preReqResult);
                debugLog("serviceLocationReqs::dropOffInshopReqs:", dropOffInshopReqs, !preReqResult);
                debugLog("serviceLocationReqs:: result", serviceLocationReqs, !preReqResult);

                debugLog("isInsuranceSet::", isInsuranceSet(), !preReqResult);

                debugLog("scheduleReqs::schedule.date:", schedule.date, !preReqResult);
                debugLog("scheduleReqs::schedule.startTime:", schedule.startTime, !preReqResult);
                debugLog("scheduleReqs::schedule.endTime:", schedule.endTime, !preReqResult);
                debugLog("scheduleReqs::schedule.jobMaxMinutes:", schedule.jobMaxMinutes, !preReqResult);
                debugLog("scheduleReqs::schedule.jobMinMinutes:", schedule.jobMinMinutes, !preReqResult);

                debugLog("customerReqs::customer.firstName:", customer.firstName, !preReqResult);
                debugLog("customerReqs::customer.lastName:", customer.lastName, !preReqResult);
                debugLog("customerReqs::customer.phoneNumber:", customer.phoneNumber, !preReqResult);
                debugLog("customerReqs::customer.emailAddress:", customer.emailAddress, !preReqResult);
                debugLog("--- payment-method.vue pagePrereqs end ---", null, !preReqResult);
            }

            return preReqResult;
        },
        getPaymentMethodFromStore() {
            const piaType = store.getters.order.payment.piaType;
            const isPia = store.getters.order.payment.isPia && !!piaType;

            return isPia ? piaType : paymentMethods.LATER;
        },
        updateFooterButtonText(newValue) {
            this.$refs.navbar.updateButtonText(newValue);
        },
        getInactivePromosFromStore() {
            return this.$store.getters.order.payment.inactivePromos;
        },
        async revalidatePromos() {
            this.$refs.loadingModal.showModal();
            const revalidatePromoResponse = await baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.REVALIDATE_ORDER_PROMOS_AND_SAVE_SERVER_DATA,
                {
                    activePromosToUse: this.lineItems.promos,
                    inactivePromosToUse: this.inactivePromos,
                    lineItemsToUse: this.lineItems,
                },
                "payment-method",
                false
            );

            // Handle error alerts here, success alerts are handled in the watcher
            if (revalidatePromoResponse.errors.length) {
                getNewlyInactivatedPromos(
                    this.inactivePromos,
                    revalidatePromoResponse.errors
                ).forEach((promoCode) => {
                    const errorAlert = createPromoErrorAlert(promoCode);
                    this.$refs.funnelHeader.pushGlobalAlert(errorAlert, errorAlert.shouldAutoFade);
                });
            }

            const vapsToAddToCart = getVapsThatNeedToBeAddedToSatisfyPromos(
                revalidatePromoResponse.promoLineItems,
                this.availableVaps,
                this.lineItems
            );

            this.lineItems.vaps.push(...vapsToAddToCart);

            this.lineItems.promos = revalidatePromoResponse.promoLineItems;
            this.inactivePromos = revalidatePromoResponse.errors.map((x) =>
                getPromoCodeWithoutBundleIdentifier(x.promoCode)
            );

            if (revalidatePromoResponse.promoLineItems.length > 0) {
                await baseMixin.methods.dispatchStoreActionWithLogging(
                    storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
                    {
                        billToAccountNumber: store.getters.payment.billToAccountNumber,
                        providerNumber:
                            this.$store.getters.order.serviceLocation.provider.providerNumber,
                        appointmentType: this.$store.getters.order.serviceLocation.appointmentType,
                        serviceLocationCity: this.$store.getters.order.serviceLocation.city,
                        serviceLocationState: this.$store.getters.order.serviceLocation.state,
                        serviceLocationZipCode: this.$store.getters.order.serviceLocation.zipCode,
                        pricedLineItems: this.lineItems,
                    },
                    "payment-method",
                    false
                );
            }

            // SAVE PROMO CHANGES TO STORE
            this.dispatchStoreAction(
                storeActions.SAVE_ACTIVE_AND_OR_INACTIVE_PROMOS,
                {
                    activePromos: this.lineItems.promos,
                    inactivePromos: this.inactivePromos,
                },
                false
            );

            this.$refs.loadingModal.hideModal();
        },
        getIsRecalAckOptInFromStore() {
            return this.$store.getters.order.isRecalAckOptIn;
        },
        backButtonAction() {
            this.$router.navigateWithoutSaving(
                this.navigationScenarios.CLICKED_BACK,
                this.pageName
            );
        },
        async forwardButtonAction() {
            this.forwardClicked = true;

            this.$refs.loadingModal.showModal();

            await this.dispatchStoreAction(
                storeActions.SAVE_PAYMENT_METHOD_CHOICE,
                this.paymentMethod,
                false
            );

            // save lineitems as they now have salestax added
            await this.dispatchStoreAction(
                storeActions.SAVE_GLASS_PARTS_SUPPRESSING_STATE_RESETTING,
                this.lineItems.glassParts,
                false
            );
            await this.dispatchStoreAction(
                storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING,
                this.lineItems.supportingItems,
                false
            );
            await this.dispatchStoreAction(storeActions.SAVE_VAPS, this.lineItems.vaps, false);
            this.dispatchStoreAction(
                storeActions.SAVE_ACTIVE_AND_OR_INACTIVE_PROMOS,
                {
                    activePromos: this.lineItems.promos,
                    inactivePromos: this.inactivePromos,
                },
                false
            );
            this.dispatchStoreAction(storeActions.SAVE_IS_RECAL_ACK_OPT_IN, this.isRecalAckOptIn);
            if (this.paymentMethod == paymentMethods.LATER) {
                // this creates the final work order
                await submitWorkOrder({ pageNameToLog: "payment-method", submitAfterSave: true });
                this.$router.navigateWithoutSaving(
                    this.navigationScenarios.CLICKED_FORWARD,
                    this.pageName
                );
            } else {
                if (this.paymentMethod == paymentMethods.INSURANCE) {
                    this.dispatchStoreAction(this.storeActions.SAVE_PAYMENT_TYPE, true, false);
                    return this.$router.navigateWithSaving(
                        this.navigationScenarios.CLICKED_INSURANCE,
                        this.pageName
                    );
                } else {
                    this.setupPia();
                }
            }
        },
        async setupPia() {
            // we need a work order number for pia so we can pass it to safeliteHop.
            // this will create one in delete substatus.
            try {
                await submitWorkOrder({
                    pageNameToLog: "payment-method",
                    submitAfterSave: false,
                    createUnscheduledStatusWorkOrderForPIA: true,
                });
            } catch (error) {
                console.log("error: response from pia submit work order:" + error.message);
                this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
                this.$route.query.piaError = true;
                return;
            }

            this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
            this.$router.navigateWithoutSaving(
                this.navigationScenarios.CLICKED_PAY_NOW,
                this.pageName
            );
        },
        async evaluatePromosAndTaxItemsOnOrder() {
            //Revalidate promos if there are any inactive, or active promos
            const hasInactivePromos = this.inactivePromos.length > 0;
            const hasActivePromos = this.lineItems.promos.length > 0;
            if (hasInactivePromos || hasActivePromos) {
                await this.revalidatePromos();
            }
            this.lineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
                {
                    billToAccountNumber: store.getters.payment.billToAccountNumber,
                    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: this.lineItems,
                },
                "payment-method",
                false
            );
        },
        hasSubmittedOrder() {
            return baseMixin.methods.hasSubmittedOrder();
        },
        getSubmittedOrder() {
            return baseMixin.methods.getSubmittedOrder();
        },
        openModal(modalName) {
            this.$refs[modalName].openModal();
        },
    },
    computed: {
        AppointmentType() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.serviceLocation?.appointmentType
                : this.$store.getters.order.serviceLocation?.appointmentType;
        },
        ServiceLocationFullAddressText() {
            return `${this.ServiceLocationAddress?.toLowerCase()}${this.ServiceLocationAddress2 ? ", " + this.ServiceLocationAddress2 : ""}, ${this.ServiceLocationCity?.toLowerCase()}, ${this.ServiceLocationState} ${this.ServiceLocationZipCode}`;
        },
        ServiceLocationFullAddress() {
            if (this.AppointmentType === AppointmentTypeStrings.MOBILE) {
                return {
                    streetAddress: this.$store.getters.order.serviceLocation?.address,
                    address2: this.$store.getters.order.serviceLocation?.address2,
                    city: this.$store.getters.order.serviceLocation?.city,
                    state: this.$store.getters.order.serviceLocation?.state,
                    zipCode: this.$store.getters.order.serviceLocation?.zipCode,
                };
            } else {
                return this.$store.getters.order.serviceLocation?.provider?.address;
            }
        },
        ServiceLocationAddress() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.serviceLocation?.address
                : this.ServiceLocationFullAddress.streetAddress;
        },
        ServiceLocationAddress2() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.serviceLocation?.address
                : this.ServiceLocationFullAddress.address2;
        },
        ServiceLocationCity() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.serviceLocation?.city
                : this.ServiceLocationFullAddress.city;
        },
        ServiceLocationState() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.serviceLocation?.state
                : this.ServiceLocationFullAddress.state;
        },
        ServiceLocationZipCode() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.serviceLocation?.zipCode
                : this.ServiceLocationFullAddress.zipCode;
        },
        AppointmentWordingText() {
            const text = this.getCmsContent("ApptDetailsSnapshotWidget", "BodyText")?.replaceAll(
                "{custom:ADDRESS}",
                this.ServiceLocationFullAddressText
            );

            return text?.replace(/\barriving between\b/gi, "<span>arriving between</span>");
        },
        isRecalibrationOnOrder() {
            const order = baseMixin.methods.hasSubmittedOrder()
                ? baseMixin.methods.getSubmittedOrder()
                : this.$store.getters.order;

            return containsRecalParts(order.lineItems);
        },
        shouldHideRecalibration() {
            return this.$store.getters.shouldHideRecalibration;
        },
        showApplePay() {
            return baseMixin.methods.showApplePay();
        },
        damageInfo() {
            return this.$store.getters.damage;
        },
        isMSRFeeApplicable() {
            return this.$store.getters.order.isMSRFeeApplicable;
        },
        isInsurance() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.payment.isInsurance
                : this.$store.getters.payment.isInsurance;
        },
        isNoComp() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.policy.isNoComp
                : this.$store.getters.policy.isNoComp;
        },
        isItac() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.policy.isItac
                : this.$store.getters.policy.isItac;
        },
        hasVapsInCart() {
            if (this.lineItems?.vaps?.length > 0) {
                return true;
            }
            return false;
        },
        showInsuranceCoverageAs() {
            if (!this.isInsurance) return null;

            if (this.isNoComp || this.isItac) {
                return coverageStatus.NOCOMP;
            }

            if (this.$store.getters.coverageIsVerified) {
                return coverageStatus.VERIFIED;
            }

            return coverageStatus.PENDING;
        },
        currentDeductible() {
            return this.hasSubmittedOrder()
                ? this.getSubmittedOrder()?.policy.currentDeductible
                : this.$store.getters.policy.currentDeductible;
        },
        insuranceCompanyName() {
            return this.$store.getters.policy.insuranceCompanyName;
        },
        noPiaDisclaimer() {
            return this.getCmsContent("NoPiaDisclaimerWidget", "Text");
        },
        customCtaCopy() {
            switch (this.paymentMethod) {
                case paymentMethods.PAY_NOW:
                    return "Continue"; // Before Heritage Parity it was "Continue to checkout"
                case paymentMethods.INSURANCE:
                    return "Continue"; // Before Heritage Parity it was "Continue to insurance"
                case paymentMethods.CREDIT_CARD:
                    return "Continue"; // Before Heritage Parity it was "Continue to checkout"
                case paymentMethods.PAYPAL:
                    return "Continue"; // Before Heritage Parity it was "Continue to Paypal"
                case paymentMethods.AFTERPAY:
                    return "Continue"; // Before Heritage Parity it was "Continue to Afterpay"
                default:
                    return null;
            }
        },
        showPaymentMethodQuestions() {
            if (this.isInsurance) {
                if (this.isPiaEnabled && this.totalAmountDue > 0) {
                    return true;
                }
            } else {
                if (this.isPiaEnabled && this.totalAmountDue > 0 && !this.shouldHideRecalibration) {
                    return true;
                }
            }

            return false;
        },
        totalAmountDue() {
            return getAmountDue(this.lineItems);
        },
        isPiaEnabled() {
            const piaExperience = this.getSettingValue(experimentSettings.PIA_EXPERIENCE);
            const piaInsurance = this.getSettingValue(experimentSettings.PIA_INSURANCE);

            if (this.isInsurance) {
                return piaInsurance === "true" && this.currentDeductible > 0;
            } else {
                return piaExperience === "PIA Optional" || piaExperience === "PIA Required";
            }
        },
        paymentMethod() {
            if (!this.isPiaEnabled) {
                return paymentMethods.LATER;
            }

            return this.paymentMethodInternalModel;
        },
        shouldDisplayPiaAlert() {
            return getBoolFromString(this.$route?.query?.piaError);
        },
        // Necessary to make the watcher of lineItems work
        // JavaScript does not keep a record of the old value, only a reference to it's location in the memory.
        //  This creates a separate location for oldValue/newValue so they can be compared
        // See Vue github issue #2164
        lineItemsCloneForWatcher() {
            return Object.assign({}, this.lineItems);
        },
        isRecalPriceRemove() {
            return (
                !this.isInsurance &&
                this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)?.toLowerCase() ===
                    "true" &&
                this.isRecalibrationOnOrder
            );
        },
        isAfterpayBreakoutDisplay() {
            return (
                this.showInsuranceCoverageAs !== coverageStatus.PENDING &&
                !this.isRecalPriceRemove &&
                this.isPiaEnabled &&
                this.hasSettingEqualTo(experimentSettings.DISPLAY_AFTERPAY_BREAKOUT_DISPLAY, "true")
            );
        },
    },
    watch: {
        customCtaCopy(newValue) {
            this.updateFooterButtonText(newValue);
        },
        lineItemsCloneForWatcher: {
            handler(newValue, oldValue) {
                if (
                    !oldValue ||
                    oldValue.length == 0 ||
                    !oldValue.vaps ||
                    !newValue ||
                    newValue.length == 0
                ) {
                    return;
                }
                if (oldValue.promos.length < newValue.promos.length) {
                    const oldPromoCodes = oldValue.promos.map(
                        (promoObject) => promoObject.promoCode
                    );

                    const newlyActivatedPromoCodes = newValue.promos.filter(
                        (newPromo) => !oldPromoCodes.includes(newPromo.promoCode)
                    );

                    // Remove any existing promo error alerts for this promo code
                    const existingAlerts = this.$refs.funnelHeader.getGlobalAlerts();
                    if (existingAlerts.length > 0) {
                        const errorPromoAlertToRemove = existingAlerts.find(
                            (alert) =>
                                alert.messageHeadline === "Promo code error" &&
                                alert.messageCopy.includes(newlyActivatedPromoCodes[0].promoCode)
                        );
                        errorPromoAlertToRemove &&
                            this.$refs.funnelHeader.removeGlobalAlert(errorPromoAlertToRemove.id);
                    }

                    const alert = createPromoSuccessAlert(newlyActivatedPromoCodes[0].promoCode);
                    this.$refs.funnelHeader.pushGlobalAlert(alert, alert.shouldAutoFade);
                } else if (
                    oldValue.promos.length == newValue.promos.length &&
                    oldValue.vaps.length != newValue.vaps.length
                ) {
                    this.revalidatePromos();
                }
            },
            deep: true,
        },
    },
    components: {
        funnelHeader,
        navbar,
        funnelSubHeader,
        Form,
        Field,
        loadingModal,
        cart,
        alert,
        paymentMethodQuestion,
        reviewDropdown,
        textBlock,
        checkboxQuestion,
        contentGroupModal,
        afterpayBreakout,
        ErrorMessage,
    },
};
</script>

<style></style>

<style lang="scss" scoped>
.appt-details-snapshot {
    :deep(p) {
        margin: 0.75rem 0 1rem 0;
        font-size: 0.875rem;
        padding: 0;
        text-transform: capitalize;
        span {
            text-transform: lowercase;
        }
    }
    :deep(.review-table p) {
        margin: 0.25rem 0 0 0;
    }
}
.checkbox-group {
    align-items: start;
    > * {
        margin-top: 0;
    }

    :deep(.form-check-input:invalid),
    :deep(.form-check-input[aria-invalid="true"]),
    :deep(.is-invalid .form-check-input) {
        border-color: $danger;
        box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
    }

    :deep(.is-invalid .form-check-label) {
        color: $danger;
    }
}
.questions-about-service {
    .service-questions {
        font-weight: 600;
    }
}
.cart {
    margin-bottom: 0;
}
.no-pia-disclaimer {
    color: $gray-550;
    margin: 0;
}
.payment-method {
    :deep(.almost-done) {
        font-family: UrbanistSemibold;
    }
    :deep(h5) {
        margin-bottom: 1rem;
    }
    .recal-modal {
        :deep(.modal-body) {
            display: flex;
            flex-direction: column;
            overflow: visible !important;

            p.subheader-text {
                color: $red;
                order: 1 !important;
                margin-top: -2.25rem;
            }
            h5 {
                text-align: left !important;
                order: 2 !important;
            }
            p {
                order: 4;
            }
            img {
                order: 3 !important;
            }
        }
    }
}
:deep(span.label) {
    font-weight: 600;
}
:deep(div.service-questions span) {
    color: $black;
    font-family: UrbanistSemibold;
}
</style>
