<template>
    <Form
        ref="theForm"
        v-slot="{ meta }"
        @submit="onSubmit"
        @invalidSubmit="onInvalidSubmit">
        <div class="fade-on-route-transition">
            <div class="justify-content-center">
                <siteHeader :cmsWidgetName="widgets.siteHeader" />
            </div>
            <div class="iss-heritage-container-width order-confirmation-container row">
                <div class="appointment-info-container col-lg-7">
                    <div class="header">
                        <img :src="orderConfirmationImage" />
                        <span
                            class="header-text"
                            v-html="orderConfirmationHeaderText"></span>
                    </div>
                    <div class="subheader">
                        <span
                            class="subheader-text"
                            v-html="orderConfirmationSubheaderText"></span>
                        <span
                            class="update-appointment-text"
                            v-html="orderConfirmationUpdateAppointmentText"></span>
                    </div>
                    <div class="service-description confirmation-section">
                        <span>{{ serviceDescriptionText }}</span>
                    </div>
                    <div class="work-order-details confirmation-section">
                        <span class="work-order-title">{{ workOrderTitle }}</span>
                        <span class="work-order-description">{{ workOrderNumber }}</span>
                    </div>
                    <div class="appointment-details confirmation-section">
                        <span class="appointment-title">{{ appointmentWordingText }}</span>
                        <span>{{ formatDate(schedule.date) }}</span>
                        <span>{{ appointmentTimeText }}</span>
                        <span class="appointment-location">{{ appointmentLocation }}</span>
                        <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="schedule.date"
                            :scheduleStartTime="schedule.startTime"
                            :scheduleEndTime="schedule.endTime"
                            :routeCode="schedule.routeCode"
                            :hasRecalibrationPart="hasRecalibrationPart"
                            :uniqueId="referralNumber"
                            :isRepair="isRepair" />
                    </div>
                    <div 
                        v-if="displayWipers"
                        class="wiper-details confirmation-section">
                        <span class="wipers-title">{{ wipersTitle }}</span>
                        <span
                            v-for="(description, index) in wipersBody"
                            :key="index"
                            class="wipers-body">{{ description }}</span>
                    </div>
                    <div 
                        v-if="displayRainRepel"
                        class="rain-repel-details confirmation-section">
                        <span class="rain-repel-title">{{ rainRepelTitle }}</span>
                        <span class="rain-repel-body">{{ rainRepelBody }}</span>
                    </div>
                    <div
                        v-if="displaySMSPhone"
                        class="sms-phone-details confirmation-section">
                        <span class="sms-phone-title">{{ smsTitle }}</span>
                        <span class="sms-phone-body">{{ contactInfo.servicePhone }}</span>
                    </div>
                    <div class="contact-details confirmation-section">
                        <span class="contact-title">{{ contactDetailsTitle }}</span>
                        <span class="contact-body">{{ contactDetailsBody }}</span>
                    </div>
                    <siteFooter
                        v-if="carrierUrl"
                        ref="siteFooter"
                        :cmsWidgetName="widgets.siteFooter"
                        :isStackedVertically="true"
                        :isForwardActionDisabled="!meta.valid"
                        @ForwardClicked="forwardButtonAction"
                        @backClicked="navigateBack" />
                </div>
                <div class="cart-container col-lg-4 offset-lg-1 col-md-5">
                    <div class="cart-header">
                        {{ cartHeaderText }}
                    </div>
                    <cartDropdown
                        v-if="showCart"
                        class="cart-dropdown"
                        :showAsPaid="payment.isPayInAdvance"
                        :readOnly="true"
                        recyclingModalCmsWidgetName="RecycleModal"
                        servicePackageTitleWidgetName="ServicePackageTitle"
                        :submittedOrder="submittedOrder" />
                </div>
            </div>
        </div>
    </Form>
</template>
<script>
// Components
import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import addToCalendar from '@/layouts/order-confirmation/add-to-calendar/add-to-calendar.vue';
import cartDropdown from '@/iss-components/cart-dropdown/cart-dropdown.vue';

// Supporting files
import {
    fetchCmsContentForPage,
    processIfStatements,
    getStringWithCustomValues
} from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
import {
    get12HourTimeFormat,
    get12HourTimeMobileFormat,
    convertDateStringToDate,
    getDisplayTextForDurationLength
} from '@/helpers/date-helper.js';
import { toTitleCase } from '@/helpers/text-helper.js';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
import applicationConfig from '@/constants/application-config';
import widgetFields from '@/constants/cms-widget-fields.js';
import { getGlassList } from '@/helpers/damage-helper';
import partTypeStrings from '@/constants/part-type-strings';
import coverageType from '@/constants/coverage-type';

export default {
    name: 'order-confirmation',
    components: {
        Form,
        siteHeader,
        siteFooter,
        addToCalendar,
        cartDropdown
    },
    mixins: [BaseFormMixin],
    async beforeRouteEnter(to, from, next) {
        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);

        // Settle promises and get results
        const promiseResultMap = [
            {
                resultKey: 'cmsContent',
                promise: cmsContentPromise
            }
        ];
        // use resultMap to populate layout content.
        const resultMap = await settleAllPromises(promiseResultMap);

        next((vm) => {
            vm.setCmsContent(resultMap.cmsContent);
        });
    },
    setup() {
        const mainStore = useMainStore();
        const submittedOrder = mainStore.getSubmittedOrder();
        return { mainStore, submittedOrder };
    },
    data() {
        const {
            vehicle,
            serviceLocation,
            schedule,
            customer,
            contactInfo,
            payment,
            customerPortalLoginToken,
            damage,
            referralNumber,
            hasRecalibrationPart
        } = this.submittedOrder;
        const { issConfig } = this.mainStore;
        return {
            vehicle,
            customerEmail: customer?.emailAddress,
            payment,
            schedule,
            serviceLocation,
            contactInfo,
            appointmentType: serviceLocation.appointmentType,
            providerAddress: serviceLocation?.provider?.address,
            customerPortalLoginToken,
            carrierName: issConfig.clientName,
            carrierUrl: issConfig.successReturnURL,
            isRepair: damage.isRepair,
            hasRecalibrationPart,
            referralNumber: referralNumber?.toString(),
            isNoComp: this.submittedOrder.insuranceCoverage.coverageType === coverageType.NO_COMP,
            widgets: {
                siteHeader: 'SiteHeaderWidget',
                emailConfirmation: 'EmailConfirmationWordingWidget',
                emailConfirmationNoComp: 'EmailConfirmationNoCompWordingWidget',
                orderConfirmation: 'OrderConfirmationContent',
                serviceDescription: 'ServiceDescriptionTextWidget',
                workOrderNumberTitle: 'WorkOrderNumberTextWidget',
                mobile: 'MobileWordingWidget',
                dropOffAndInShop: 'DropOffAndInShopWordingWidget',
                wipersText: 'WipersTextWidget',
                rainRepel: 'RainRepelWidget',
                smsUpdates: 'SmsUpdatesWidget',
                contactDetails: 'ContactDetailsWidget',
                vapsItemDescriptions: 'VapsItemDescriptions',
                payAtAppointment: 'PayAtAppointmentTextWidget',
                orderDetails: 'OrderDetailsTextWidget',
                siteFooter: 'SiteFooterWidget'
            }
        };
    },
    computed: {
        customValueMap() {
            return {
                inShopAppointment: this.isInShopAppointment,
                dropOffAppointment: this.isDropOffAppointment,
                vehicleYear: this.vehicle?.year,
                vehicleMake: this.vehicle?.make,
                vehicleModel: this.vehicle?.model,
                serviceType: this.serviceTypeText,
                address: this.appointmentLocation,
                inShopDuration: this.inShopAppointmentDuration,
                email: this.customerEmail,
                phone: this.contactPhone,
                workOrderNumber: this.workOrderNumber,
                CUSTOMER_PORTAL_URL: applicationConfig.CUSTOMER_PORTAL_URL,
                CUSTOMER_PORTAL_LOGIN_TOKEN: this.customerPortalLoginToken
            };
        },
        orderConfirmationUpdateAppointmentText() {
            let content = '';
            if (this.isNoComp) {
                content = this.getCmsContentWithCustomValues(
                    this.widgets.emailConfirmationNoComp,
                    widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
                );
            } else {
                content = this.getCmsContentWithCustomValues(
                    this.widgets.emailConfirmation,
                    widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
                );
            }
            return content
                ?.replaceAll('&lt;', '<')
                ?.replaceAll('&gt;', '>');
        },
        orderConfirmationHeaderText() {
            return this.getCmsContent(
                this.widgets.orderConfirmation,
                widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
            );
        },
        orderConfirmationImage() {
            return this.getCmsContent(
                this.widgets.orderConfirmation,
                widgetFields.CONTENT_GROUP_WIDGET.IMAGE
            );
        },
        orderConfirmationSubheaderText() {
            return this.getCmsContent(
                this.widgets.orderConfirmation,
                widgetFields.CONTENT_GROUP_WIDGET.SUBHEADER_TEXT
            );
        },
        serviceDescriptionText() {
            const content = this.getCmsContentWithCustomValues(
                this.widgets.serviceDescription,
                widgetFields.TEXT_BLOCK_WIDGET.TEXT
            );
            return content;
        },
        serviceTypeText() {
            const glassPieces = this.submittedOrder.lineItems.glassParts?.map((part) => part.partType.toLowerCase()) ?? [];
            let glassList = '';
            let workType = '';
            if (this.isRepair) {
                glassList = 'windshield';
                workType = 'repair';
            } else {
                glassList = getGlassList(glassPieces);
                workType = 'replacement';
                if (this.hasRecalibrationPart) {
                    if (glassList === 'windshield') {
                        workType = 'replacement and recalibration';
                    }
                    else {
                        glassList = glassList.replace('windshield', 'windshield replacement, recalibration');
                    }
                }
            }
            return `${glassList} ${workType}`;
        },
        workOrderTitle() {
            return this.getCmsContent(
                this.widgets.workOrderNumberTitle,
                widgetFields.TEXT_BLOCK_WIDGET.TEXT
            );
        },
        workOrderNumber() {
            return this.submittedOrder.workOrderNumber;
        },
        mobileWordingText() {
            return this.getCmsContentWithCustomValues(
                this.widgets.mobile,
                widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
            );
        },
        mobileWordingText2() {
            return this.getCmsContent(
                this.widgets.mobile,
                widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2
            );
        },
        nonMobileWordingText() {
            return this.getCmsContentWithCustomValues(
                this.widgets.dropOffAndInShop,
                widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
            );
        },
        nonMobileWordingText2() {
            return this.getCmsContentWithCustomValues(
                this.widgets.dropOffAndInShop,
                widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2
            );
        },
        appointmentTimeText() {
            const { startTime, endTime } = this.schedule;
            if (this.isDropOffAppointment) {
                return 'Drop off before 9:30 AM';
            }
            if (this.isInShopAppointment) {
                const formattedStartTime = get12HourTimeFormat(startTime);
                return `Your appointment is at ${formattedStartTime}`;
            }
            if (this.isMobileAppointment) {
                const mobileStartTime = get12HourTimeMobileFormat(startTime);
                const mobileEndTime = get12HourTimeMobileFormat(endTime);
                return `Your appointment is at ${mobileStartTime} - ${mobileEndTime}`;
            }
            return null;
        },
        appointmentLocation() {
            if (this.isMobileAppointment) {
                return this.serviceLocationFullAddress;
            }
            if (this.isDropOffAppointment || this.isInShopAppointment) {
                return this.providerFullAddress;
            }
            return null;
        },
        serviceLocationFullAddress() {
            const { address, address2, city, state, zipCode } = this.serviceLocation;
            return `${address ?? ''}, ${address2 ? `${address2},` : ''} ${city ?? ''}, ${state ?? ''} ${zipCode ?? ''}`;
        },
        providerFullAddress() {
            const { streetAddress, city, state, zipCode } = this.providerAddress;
            return streetAddress
                ? `${toTitleCase(streetAddress)}, ${toTitleCase(city)}, ${state ?? ''} ${zipCode ?? ''}`
                : '';
        },
        appointmentWordingText() {
            if (this.isMobileAppointment) {
                return this.mobileWordingText;
            }
            if (this.isInShopAppointment || this.isDropOffAppointment) {
                return this.nonMobileWordingText;
            }
            return null;
        },
        appointmentWordingText2() {
            if (this.isMobileAppointment) {
                return this.mobileWordingText2;
            }
            if (this.isInShopAppointment || this.isDropOffAppointment) {
                return this.nonMobileWordingText2;
            }
            return null;
        },
        isMobileAppointment() {
            const mobileAppointmentTypes = [
                AppointmentTypeStrings.MOBILE,
                AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP
            ];
            return mobileAppointmentTypes.includes(this.appointmentType);
        },
        isInShopAppointment() {
            return this.appointmentType === AppointmentTypeStrings.IN_SHOP;
        },
        isDropOffAppointment() {
            return this.appointmentType === AppointmentTypeStrings.DROP_OFF;
        },
        inShopAppointmentDuration() {
            return getDisplayTextForDurationLength(
                this.schedule.jobMinMinutes,
                this.schedule.jobMaxMinutes
            );
        },
        showCart() {
            if (!this.payment.isPayInAdvance) {
                return true;
            }

            if (this.submittedOrder.settledTenderAmount > 0) {
                return true;
            }

            // settleTenderAmount always shows 0 via localhost or dev.
            // Temporarily set return true to see cart in localhost or dev environment
            return false;
        },
        displayWipers() {
            const hasWiperPart = this.submittedOrder.lineItems.vaps.some((part) => part.partType.toLowerCase().includes('wiper'));
            return hasWiperPart;
        },
        wipersTitle() {
            return this.getCmsContent(
                this.widgets.wipersText,
                widgetFields.TEXT_BLOCK_WIDGET.TEXT
            );
        },
        wipersBody() {
            const wiperTypesOnOrder = [];

            const hasFrontWiper = this.submittedOrder.lineItems.vaps.some((part) => part.partType === partTypeStrings.FRONT_WIPER);
            const hasRearWiper = this.submittedOrder.lineItems.vaps.some((part) => part.partType === partTypeStrings.REAR_WIPER);

            if (hasFrontWiper) {
                wiperTypesOnOrder.push(partTypeStrings.FRONT_WIPER);
            }
            if (hasRearWiper) {
                wiperTypesOnOrder.push(partTypeStrings.REAR_WIPER);
            }

            const wiperDescriptions = wiperTypesOnOrder.map((type) => {
                return this.getCmsContentForVapsType(type);
            });

            return wiperDescriptions;
        },
        displayRainRepel() {
            return this.submittedOrder.lineItems.vaps.some((part) => part.partType === partTypeStrings.RAIN_DEFENSE);
        },
        rainRepelTitle() {
            return this.getCmsContent(
                this.widgets.rainRepel,
                widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
            );
        },
        rainRepelBody() {
            return this.getCmsContent(
                this.widgets.rainRepel,
                widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
            );
        },
        displaySMSPhone() {
            return this.contactInfo.requestTextUpdates && this.contactInfo.servicePhone;
        },
        smsTitle() {
            return this.getCmsContent(
                this.widgets.smsUpdates,
                widgetFields.TEXT_BLOCK_WIDGET.TEXT
            );
        },
        contactDetailsTitle() {
            return this.getCmsContent(
                this.widgets.contactDetails,
                widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
            );
        },
        contactDetailsBody() {
            return this.getCmsContentWithCustomValues(
                this.widgets.contactDetails,
                widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
            );
        },
        cartHeaderText() {
            if (this.payment.isPayInAdvance) {
                return this.getCmsContent(
                    this.widgets.orderDetails,
                    widgetFields.TEXT_BLOCK_WIDGET.TEXT
                );
            } else {
                return this.getCmsContent(
                    this.widgets.payAtAppointment,
                    widgetFields.TEXT_BLOCK_WIDGET.TEXT
                );
            }
        },
        contactPhone() {
            let phoneNumber = this.contactInfo.servicePhone;
            if (this.contactInfo.extension) {
                phoneNumber += `-${this.contactInfo.extension}`;
            }
            return phoneNumber;
        }
    },
    mounted() {
        if (this.carrierUrl) {
            this.$refs.siteFooter.updateButtonText(`Go back to ${this.carrierName}`);
        }
    },
    methods: {
        arePagePrerequisitesValid() {
            const hasSubmittedOrder = useMainStore().hasSubmittedOrder();
            if (hasSubmittedOrder) {
                return true;
            }

            // Service Location
            const { serviceLocation } = useMainStore().order;
            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
                || serviceLocation.appointmentType
                    === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;

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

            // Insurance
            const isInsuranceSet =
                useMainStore().order.payment.isInsurance !== null;

            // Schedule
            const { schedule } = useMainStore().order;
            const scheduleReqs = !!(
                schedule.date
                && schedule.startTime
                && schedule.endTime
                && schedule.jobMaxMinutes
                && schedule.jobMinMinutes
            );

            // Contact Info
            const { contactInfo } = useMainStore();
            const contactInfoReqs = !!(
                contactInfo.firstName
                && contactInfo.lastName
                && contactInfo.servicePhone
                && contactInfo.emailAddress
            );

            // Payment
            const paymentMethodReqs = useMainStore().order.payment.paymentMethod != null;

            return (
                serviceLocationReqs
                && isInsuranceSet
                && scheduleReqs
                && contactInfoReqs
                && paymentMethodReqs
            );
        },
        forwardButtonAction() {
            this.$router.navigateToExternalUrl(this.carrierUrl);
        },
        getCmsContentWithCustomValues(widgetName, widgetField) {
            const rawText = this.getCmsContent(widgetName, widgetField);
            const processedIfStatements = processIfStatements(
                rawText,
                'custom',
                (v) => this.customValueMap[v]
            );
            return getStringWithCustomValues(processedIfStatements, this.customValueMap);
        },
        formatDate(date) {
            // This conversion ensures we don't get get GMT induced date changes
            const dateObject = convertDateStringToDate(date);
            // Ex: Tuesday, April 22
            return dateObject.toLocaleDateString('en-us', {
                weekday: 'long',
                month: 'long',
                day: 'numeric',
                year: 'numeric'
            });
        },
        getCmsContentForVapsType(vapsPartType) {
            const vapsItemDescriptions = this.getCmsContent(
                this.widgets.vapsItemDescriptions,
                widgetFields.INPUT_QUESTION_WIDGET.ANSWERS
            );

            if (!vapsItemDescriptions) {
                return '';
            }

            const vapsTypeDescription = vapsItemDescriptions?.find((entry) => entry?.Name === vapsPartType);
            return vapsTypeDescription?.Text ?? '';
        }
    }
};
</script>
<style lang="scss" scoped>
.order-confirmation-container {    
    .appointment-info-container
    {
        padding: 0 .9375rem;
        margin-bottom: 1.875rem;
    }

    .cart-container {
        padding: 0 .9375rem 2.1875rem;
    }

    .header {
        flex-direction: row;
        margin-top: 1.25rem;
        margin-bottom: .625rem;
        font-size: 1.25rem;
        color: $black;

        img {
            width: 2.25rem;
            height: 2.25rem;
            margin-right: 1rem;
        }
    }

    .subheader {
        display: flex;
        flex-direction: column;
        margin-top: 1.25rem;

        .subheader-text {
            margin-bottom: .625rem;
            font-size: 1rem;
            font-weight: 500;
            color: $black;
        }

        .update-appointment-text {
            :deep(.text-primary) {
                color: $heritage-blue-primary;
            }
            :deep(a) {
                font-weight: $font-weight-bold;
                color: $heritage-blue-primary;
                text-decoration: none;

                &:hover {
                    color: $heritage-blue-secondary;
                    text-decoration: underline;
                }
            }
        }
    }

    .confirmation-section {
        display: flex;
        flex-direction: column;
        padding: 1.875rem 0;
        border-bottom: 1px solid lightgray;

        >:first-child {
            font-weight: 600;
            color: $black;
        }
    }

    .service-description {
        >span:first-child {
            font-weight: $font-weight-bold;
        }
    }

    .work-order-title {
        margin-bottom: .625rem;
    }

    .appointment-details {
        padding-bottom: 2.0625rem;

        .appointment-title {
            margin-bottom: .625rem;
        }

        .appointment-location {
            margin-top: .625rem;
        }
    }

    .rain-repel-details {
        .rain-repel-title {
            color: #4d4e53;
        }
    }

    .sms-phone-details {
        .sms-phone-title {
            color: #4d4e53;
        }
    }

    .contact-details {
        .contact-title {
            margin-bottom: .625rem;
        }
    }

    .cart-header {
        margin-top: 1.25rem;
        margin-bottom: .625rem;
        color: $black;
        font-weight: $font-weight-bold;
    }

    .cart-dropdown:deep(.deductible-value) {
        font-size: 1rem;
        font-weight: $font-weight-bold;
    }
}
</style>
