<template>
    <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
        <div class="page-container-grouped-styles position-relative">
            <div>
                <div class="container-fluid pb-2">
                    <div class="row justify-content-center">
                        <div class="col-md-6">
                            <funnelHeader
                                cmsWidgetName="FunnelHeaderWidget"
                                ref="funnelHeader"
                                hideSalesforceWebchatLaunchButton />
                        </div>
                    </div>
                    <div class="row justify-content-center">
                        <div class="col-md-6 col-xl-4">
                            <div class="header-container">
                                <img :src="ScheduleConfirmationImage" />
                                <span v-html="ScheduleConfirmationText"></span>
                            </div>
                            <div class="main">
                                <div></div>

                                <div class="scheduleText">
                                    <p>{{ ScheduleDateFormatted }}</p>
                                    <p>{{ ScheduleTimeFormatted }}</p>
                                </div>

                                <addToCalendar
                                    mobileWidgetName="AddToCalendar_Mobile"
                                    inShopWidgetName="AddToCalendar_InShop"
                                    dropOffWidgetName="AddToCalendar_DropOff"
                                    overnightDropOffWidgetName="AddToCalendar_OvernightDropOff"
                                    allDayDropOffWidgetName="AddToCalendar_AllDayDropOff"
                                    sameDayDropOffWidgetName="AddToCalendar_SameDayDropOff"
                                    :serviceLocationFullAddress="ServiceLocationFullAddress"
                                    :providerFullAddress="ProviderFullAddress"
                                    :appointmentType="AppointmentType"
                                    :scheduleDate="ScheduleDate"
                                    :scheduleStartTime="ScheduleStartTime"
                                    :scheduleEndTime="ScheduleEndTime" />

                                <div class="appointment-text" v-html="AppointmentWordingText"></div>

                                <textBlock
                                    :customText="AppointmentDuration"
                                    justifyText="center"
                                    typeStyle="medium"
                                    class="duration-text-block" />
                            </div>

                            <hr class="mt-4 mb-0" />

                            <cart
                                v-if="ShowCart"
                                :damage="damageInfo"
                                :availableVaps="vaps"
                                :allowItemRemoval="false"
                                v-model="lineItems"
                                :showAsPaid="isPia"
                                servicePackageOptionsCmsName="ServicePackageTitle"
                                :isInsurance="isInsurance"
                                :insuranceDeductible="currentDeductible"
                                :insuranceCompanyName="insuranceCompanyName"
                                :showInsuranceCoverageAs="showInsuranceCoverageAs"
                                :shouldHideRecalibration="shouldHideRecalibration"
                                :isExpandedOnLoad="false"
                                :isItac="isItac"
                                :isNoComp="isNoComp"
                                :isMSRFeeApplicable="isMSRFeeApplicable" />

                            <div class="mt-3" v-if="shouldDisplayFosterLove">
                                <donationBlock
                                    cmsWidgetName="DonationWidget"
                                    v-model="donationAmount"
                                    :donationValues="donationValues"
                                    :showDonationSuccess="showDonationSuccess"
                                    :showDonationError="showDonationError"
                                    @DonationAddedEvent="addDonationToOrder"
                                    ref="donationBlock" />
                            </div>

                            <hr class="mb-5" />

                            <div class="emailtext" v-html="ConfirmationEmailText"></div>

                            <navbar
                                cmsWidgetName="FunnelFooterWidget"
                                ref="navbar"
                                isBackButtonHidden="true"
                                @ForwardClicked="forwardButtonAction"
                                :buttonSize="true" />
                        </div>
                    </div>
                </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 addToCalendar from "@/layouts/confirmation/add-to-calendar/add-to-calendar";
import cart from "@/fmg-components/cart/cart";
import textBlock from "@/digital-components/text-block/text-block";

//Supporting files
import baseMixin from "@/mixins/base-mixin.js";
import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
import { settleAllPromises } from "@/helpers/layout-helper";
import { applicationConfig } from "@/constants/application-config.js";
import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper";
import { deepClone } from "@/helpers/object-helper";
import { Form } from "vee-validate";
import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-helper";
import { coverageStatus } from "@/constants/insurance";
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
import { experimentSettings } from "@/constants/experiments";
import experimentMixin from "@/mixins/experiment-mixin.js";
import { containsRecalParts } from "@/helpers/recal-helper.js";
import donationBlock from "@/experiment-components/donation-block.vue";
import { partNumberStrings } from "@/constants/part-number-strings";

export default {
    name: "confirmation",
    async beforeRouteEnter(to, from, next) {
        // Experiments
        const hasRecalPriceRemoveExperiment = await store.getters.shouldHideRecalibration;
        let applicationUser = baseMixin.methods.hasSubmittedApplicationUser()
            ? baseMixin.methods.getSubmittedApplicationUser()
            : store.getters.applicationUser;
        let hasFosterLoveExperiment = experimentMixin.methods.hasSettingEqualTo(
            experimentSettings.FOSTER_LOVE,
            "true",
            applicationUser.experiments
        );

        // send part question data to SPS API for logging
        const orderFromStore = await deepClone(store.getters.order);
        const ctu = orderFromStore.serviceLocation?.zipCodeCtu;

        const partsOrQuestions = orderFromStore.damage?.partQuestionAnswers;

        if (partsOrQuestions) {
            partsOrQuestions.forEach((pqa) => {
                const payloadPartQuestions = [];
                pqa.answeredQuestions.forEach((answer) => {
                    payloadPartQuestions.push({
                        questionSeq: answer?.questionNum,
                        questionText: answer?.questionText,
                        answerText: answer?.selectedAnswerText,
                        basePart: pqa?.result,
                    });
                });

                const payload = {
                    eon: orderFromStore.eon,
                    ctu: ctu,
                    workOrderId: orderFromStore.workOrderId,
                    workOrderNumber: orderFromStore.workOrderNumber,
                    carId: orderFromStore.vehicle.carId,
                    glassLocation: pqa?.glassLocation,
                    partQuestions: payloadPartQuestions,
                };

                baseMixin.methods.dispatchStoreAction(
                    storeActions.LOG_PART_QUESTIONS,
                    payload,
                    false
                );
            });
        }

        // Create order
        await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_STATE); // This nulls the Store order

        // Call APIs
        const submittedOrder = baseMixin.methods.getSubmittedOrder();
        const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);

        const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.GET_WIPERS,
            {
                serviceZipCode: submittedOrder.serviceLocation.zipCode,
                carId: submittedOrder.vehicle.carId,
            },
            "confirmation"
        );

        const rainDefensePromise = baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.GET_RAIN_DEFENSE,
            null,
            "confirmation"
        );

        // Settle promises and get results
        const promiseResultMap = [
            {
                resultKey: "cmsContent",
                promise: cmsContentPromise,
            },
            {
                resultKey: "wipers",
                promise: wipersPromise,
            },
            {
                resultKey: "rainDefense",
                promise: rainDefensePromise,
            },
        ];

        const resultMap = await settleAllPromises(promiseResultMap);
        const availableVaps = [resultMap.rainDefense, ...resultMap.wipers];
        const lineItemsFromSubmittedOrder = deepClone(submittedOrder.lineItems);

        const isNoComp = submittedOrder?.policy?.isNoComp;
        const isItac = submittedOrder?.policy?.isItac;
        const isRecalibrationOnOrder = containsRecalParts(lineItemsFromSubmittedOrder);

        const shouldHideRecalibration = () => {
            if (isNoComp || isItac) {
                return false;
            }
            return hasRecalPriceRemoveExperiment && isRecalibrationOnOrder;
        };

        const donationItems = lineItemsFromSubmittedOrder.supportingItems?.filter(
            (item) => item.partNumber === partNumberStrings.DONATION
        );
        const donationAmount = donationItems?.length > 0 ? donationItems[0].sellingPrice : 0;

        // Call the "next" function to complete the transition to this page.
        next((vm) => {
            vm.setCmsContent(resultMap.cmsContent);
            vm.lineItems = lineItemsFromSubmittedOrder;
            vm.vaps = availableVaps;
            vm.submittedOrder = submittedOrder;
            vm.shouldHideRecalibration = shouldHideRecalibration();
            vm.shouldDisplayFosterLove = hasFosterLoveExperiment;
            vm.donationAmount = donationAmount;
            vm.showDonationSuccess = lineItemsFromSubmittedOrder.supportingItems?.some(
                (item) => item.partType === partNumberStrings.DONATION
            );
        });
    },
    data() {
        return {
            lineItems: [],
            vaps: [],
            submittedOrder: null,
            shouldHideRecalibration: null,
            shouldDisplayFosterLove: null,
            donationAmount: 0,
            showDonationSuccess: null,
            showDonationError: null,
        };
    },
    computed: {
        isRecalibrationOnOrder() {
            return containsRecalParts(this?.lineItems);
        },
        ShowCart() {
            if (this.isPia && this.submittedOrder?.settledTenderAmount == 0) {
                return false;
            }
            return true;
        },
        ScheduleConfirmationText() {
            return this.getCmsContent("ScheduleConfirmationWidget", "BodyText");
        },
        ScheduleConfirmationImage() {
            return this.getCmsContent("ScheduleConfirmationWidget", "Image");
        },
        CustomerPortalLoginToken() {
            return this.submittedOrder?.customerPortalLoginToken;
        },
        ConfirmationEmailText() {
            return this.getCmsContent("ConfirmationEmailWidget", "BodyText")
                ?.replaceAll(
                    "{custom:submittedOrder.customer.emailAddress}",
                    this.submittedOrder?.customer?.emailAddress
                )
                ?.replaceAll("{custom:MY_ACCOUNT_URL}", applicationConfig.MY_ACCOUNT)
                ?.replaceAll("{custom:CUSTOMER_PORTAL_LOGIN_TOKEN}", this.CustomerPortalLoginToken)
                ?.replaceAll("&lt;", "<")
                ?.replaceAll("&gt;", ">");
        },
        ScheduleDate() {
            return this.submittedOrder?.schedule?.date;
        },
        AppointmentType() {
            return this.submittedOrder?.serviceLocation?.appointmentType;
        },
        ScheduleStartTime() {
            return this.submittedOrder?.schedule?.startTime;
        },
        ScheduleEndTime() {
            return this.submittedOrder?.schedule?.endTime;
        },
        InShopWordingText() {
            return this.getCmsContent("InShopWordingWidget", "BodyText")
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.year}",
                    this.submittedOrder?.vehicle?.year
                )
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.make}",
                    this.submittedOrder?.vehicle?.make
                )
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.model}",
                    this.submittedOrder?.vehicle?.model
                );
        },
        MobileWordingText() {
            return this.getCmsContent("MobileWordingWidget", "BodyText")
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.year}",
                    this.submittedOrder?.vehicle?.year
                )
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.make}",
                    this.submittedOrder?.vehicle?.make
                )
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.model}",
                    this.submittedOrder?.vehicle?.model
                );
        },
        DropOffWordingText() {
            return this.getCmsContent("DropOffWordingWidget", "BodyText")
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.year}",
                    this.submittedOrder?.vehicle?.year
                )
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.make}",
                    this.submittedOrder?.vehicle?.make
                )
                ?.replaceAll(
                    "{custom:submittedOrder.vehicle.model}",
                    this.submittedOrder?.vehicle?.model
                );
        },
        ServiceLocationAddress() {
            return this.submittedOrder?.serviceLocation?.address;
        },
        ServiceLocationAddress2() {
            return this.submittedOrder?.serviceLocation?.address2;
        },
        ServiceLocationCity() {
            return this.submittedOrder?.serviceLocation?.city;
        },
        ServiceLocationState() {
            return this.submittedOrder?.serviceLocation?.state;
        },
        ServiceLocationZipCode() {
            return this.submittedOrder?.serviceLocation?.zipCode;
        },
        ProviderAddress() {
            return this.submittedOrder?.serviceLocation?.provider?.address?.streetAddress;
        },
        ProviderCity() {
            return this.submittedOrder?.serviceLocation?.provider?.address?.city;
        },
        ProviderState() {
            return this.submittedOrder?.serviceLocation?.provider?.address?.state;
        },
        ProviderZipCode() {
            return this.submittedOrder?.serviceLocation?.provider?.address?.zipCode;
        },
        AppointmentWordingText() {
            if (this.AppointmentType == AppointmentTypeStrings.MOBILE) {
                return this.MobileWordingText?.replaceAll(
                    "{custom:ADDRESS}",
                    this.ServiceLocationFullAddress
                );
            } else if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) {
                return this.DropOffWordingText?.replaceAll(
                    "{custom:ADDRESS}",
                    this.ProviderFullAddress
                );
            } else {
                return this.InShopWordingText?.replaceAll(
                    "{custom:ADDRESS}",
                    this.ProviderFullAddress
                );
            }
        },
        ServiceLocationFullAddress() {
            return `${this.ServiceLocationAddress}${this.ServiceLocationAddress2 ? ", " + this.ServiceLocationAddress2 : ""},<br/> ${this.ServiceLocationCity}, ${this.ServiceLocationState} ${this.ServiceLocationZipCode}`;
        },
        ProviderFullAddress() {
            return `${this.ProviderAddress},<br/> ${this.ProviderCity}, ${this.ProviderState} ${this.ProviderZipCode}`;
        },
        ScheduleDateFormatted() {
            // This conversion ensures we don't get get GMT induced date changes
            const dateObject = convertDateStringToDate(this.ScheduleDate);
            // Ex: Tuesday, April 22
            return dateObject?.toLocaleDateString("en-us", {
                weekday: "long",
                month: "long",
                day: "numeric",
            });
        },
        ScheduleTimeFormatted() {
            if (this.AppointmentType == AppointmentTypeStrings.MOBILE) {
                return `Between ${get12HourTimeMobileFormat(
                    this.ScheduleStartTime
                )} - ${get12HourTimeMobileFormat(this.ScheduleEndTime)}`;
            }
            if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) {
                if (
                    this.submittedOrder?.schedule?.routeCode.includes(
                        RouteCodeFlags.OVERNIGHT_DROP_OFF
                    )
                ) {
                    return `Drop off before 5:30 PM`;
                } else {
                    return `Drop off before 9:30 AM`;
                }
            }
            return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`;
        },
        vehicleBannerImageUrl() {
            return this.submittedOrder?.vehicle.imageUrl;
        },
        damageInfo() {
            return this.submittedOrder?.damage;
        },
        isMSRFeeApplicable() {
            return this.submittedOrder?.isMSRFeeApplicable;
        },
        isInsurance() {
            return this.submittedOrder?.payment?.isInsurance;
        },
        isNoComp() {
            return this.submittedOrder?.policy?.isNoComp;
        },
        isItac() {
            return this.submittedOrder?.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;
            } else {
                return this.submittedOrder?.payment?.insuranceCoverage?.coverageStatus;
            }
        },
        currentDeductible() {
            return this.submittedOrder?.policy?.currentDeductible;
        },
        insuranceCompanyName() {
            return this.submittedOrder?.policy?.insuranceCompanyName;
        },
        isPia() {
            return this.submittedOrder?.payment?.isPia;
        },
        AppointmentDuration() {
            const durationMaximum = this.submittedOrder?.schedule?.jobMaxMinutes;
            const durationMinimum = this.submittedOrder?.schedule?.jobMinMinutes;
            const durationLengthString = "Duration: ";
            if (
                this.submittedOrder?.schedule?.routeCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)
            ) {
                return durationLengthString.concat("All Day");
            } else if (
                this.submittedOrder?.schedule?.routeCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)
            ) {
                return durationLengthString.concat("Overnight");
            } else {
                return durationLengthString.concat(
                    getDisplayTextForDurationLength(durationMinimum, durationMaximum)
                );
            }
        },
        donationValues() {
            return [1, 3, 5];
        },
    },
    methods: {
        arePagePrerequisitesValid() {
            if (baseMixin.methods.hasSubmittedOrder()) {
                return true;
            }

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

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

            // Customer
            const customer = store.getters.order.customer;
            const customerReqs = !!customer.emailAddress;

            return serviceLocationReqs && scheduleReqs && customerReqs;
        },
        forwardButtonAction() {
            window.location.assign(location.protocol + "//" + location.host);
        },
        async addDonationToOrder() {
            const donationResponse = await baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.SUBMIT_DONATION_PART_TO_SV2,
                {
                    donationAmount: parseInt(this.donationAmount),
                    submittedOrder: this.submittedOrder,
                },
                false
            );

            if (donationResponse?.wasSuccessful) {
                this.showDonationSuccess = true;
                this.showDonationError = false;
                await baseMixin.methods.dispatchStoreAction(
                    storeActions.ADD_DONATION_TO_SUBMITTED_STATE,
                    parseInt(this.donationAmount),
                    false
                );
                this.lineItems = deepClone(this.getSubmittedOrder().lineItems);
                this.$refs.donationBlock.removeLoader();
            } else {
                this.showDonationError = true;
                this.showDonationSuccess = false;
                this.donationAmount = 0;
                this.$refs.donationBlock.removeLoader();
            }
        },
    },
    components: {
        funnelHeader,
        Form,
        navbar,
        addToCalendar,
        cart,
        textBlock,
        donationBlock,
    },
};
</script>

<style lang="scss">
.main {
    margin-bottom: 1.5rem;
    padding: 1rem 1.5rem 1.5rem;
    box-shadow: 0 3px 10px rgb(0 0 0 / 0.2);
    border-radius: 5px;
}
.scheduleText {
    text-align: center;
}

.scheduleText P {
    margin: 0;
    font-weight: 400;
    font-size: 1.25rem;
    color: $black;

    + p {
        font-size: 1rem;
        margin-top: 0.5rem;
        font-weight: 500;
    }
}

.header-container {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 0;

    p {
        display: inline-block;
        font-weight: 400;
        font-size: 1.25rem;
        color: $black;
        margin: 0;
    }

    img {
        margin-right: 0.5rem;
    }
}

.appointment-text {
    p {
        margin: 0;
    }
    strong {
        color: $black;
    }
}

.emailtext {
    padding: 0.5rem 0 0;

    p {
        font-size: 0.875rem;
        margin: 0;

        strong {
            color: $black;
        }
    }
}
</style>
