<template>
    <Form
        ref="theForm"
        v-slot="{ meta }"
        @submit="onSubmit"
        @invalidSubmit="onInvalidSubmit">
        <div class="fade-on-route-transition">
            <div class="justify-content-center">
                <siteHeader
                    ref="siteHeader"
                    cmsWidgetName="SiteHeaderWidget" />
            </div>
            <div class="iss-heritage-container-width payment-method-container row">
                <div class="order-info-container col-md-7">
                    <alert
                        class=""
                        alertClass="alert-warning"
                        cmsWidgetName="AlertIncompleteWidget" />
                    <siteSubHeader
                        class="subheader"
                        cmsWidgetName="SiteSubHeaderWidget" />
                    <div class="main-content-container">
                        <hr class="section-divider" />
                        <reviewDropdown
                            ref="reviewDropdown"
                            @edit-clicked="handleEditClicked"
                        />
                        <div class="cart-header">
                            <span class="cart-label">{{ cartHeaderText }}</span>
                            <span v-if="showCartTotal" class="cart-value">{{ cartTotal }}</span>
                        </div>
                        <div class="cart-dropdown-container">
                            <cartDropdown
                                :showAsPaid="false"
                                :readOnly="false"
                                recyclingModalCmsWidgetName="RecycleModal"
                                servicePackageTitleWidgetName="ServicePackageTitle" />
                        </div>
                        <alert
                            v-if="displayPayInAdvanceAlert"
                            name="payInAdvanceErrorAlert"
                            class="my-4"
                            cmsWidgetName="PayInAdvanceErrorAlertWidget"
                            alertClass="alert-danger"
                            :isDismissible="false" />
                        <hr 
                            v-if="!isPayInAdvanceDisabled"
                            class="pia-divider" />
                        <paymentMethodQuestion
                            v-if="!isPayInAdvanceDisabled"
                            v-model="paymentMethod"
                            :cmsWidgetName="paymentMethodWidgetName"
                            :validationRules="rules.optionRequired" />
                        <div
                            v-if="!isOptedInSMSPreviously"
                            class="sms-opt-in-section">
                            <hr class="sms-divider" />
                            <div class="sms-opt-in-header">{{ smsOptInHeaderText }}</div>
                            <buttonQuestion
                                class="sms-opt-in-question"
                                v-model="smsOptIn"
                                groupName="sms-opt-in"
                                buttonTypeString="listButtonHorizontal"
                                :questionText="smsOptinQuestionText"
                                :answers="smsOptinQuestionAnswers"
                                isRequired
                                :validationRules="rules.optionRequired" />
                            <textboxQuestion
                                v-if="smsOptIn === 'Yes'"
                                v-model="smsPhoneNumber"
                                inputId="phoneNumber"
                                :cmsWidgetName="widget.smsPhoneNumber"
                                isRequired
                                :mask="phoneMask"
                                placeholderText="###-###-####"
                                disableAutoFill
                                :validationRules="rules.phoneNumber" />
                        </div>
                        <siteFooter
                            ref="siteFooter"
                            cmsWidgetName="SiteFooterWidget"
                            :isForwardActionDisabled="!meta.valid"
                            @backClicked="backButtonAction"
                            @ForwardClicked="forwardButtonAction" />
                        <div
                            v-if="!isOptedInSMSPreviously"
                            class="disclaimer">
                            <textBlock :cmsWidgetName="widget.smsDisclaimer" />
                        </div>
                    </div>
                </div>
                <div class="offer-container col-lg-4 offset-lg-1 col-md-5 d-none d-md-flex">
                    <div
                        v-if="offerWipers"
                        class="wiper-offer-panel">
                        <div class="wiper-logo">
                            <img
                                :src="wiperOfferPanel.image"
                                alt="Wiper Offer Logo" />
                        </div>
                        <div class="panel-body">
                            <div class="wiper-header">{{ wiperOfferPanel.header }}</div>
                            <div class="wiper-body">{{ wiperOfferPanel.body }}</div>
                        </div>
                        <div class="panel-footer">
                            <buttonMain
                                class="edit-wiper-offer-button"
                                :buttonText="wiperOfferPanel.edit"
                                @click="handleEditClicked('wipers')" />
                        </div>
                    </div>
                </div>
            </div>
            <contactDetailsDrawer
                ref="contactDetailsDrawer"
                class="contact-details-drawer"
                @updateContactDetails="refreshContactDetails"
                @closeWithoutSaving="closeContactDetailsWithoutSaving" />
        </div>
    </Form>
</template>

<script>
// Components
import baseFormMixin from '@/mixins/base-form-mixin';
import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import reviewDropdown from '@/layouts/payment-method/review-dropdown/review-dropdown.vue';
import cartDropdown from '@/iss-components/cart-dropdown/cart-dropdown.vue';
import paymentMethodQuestion from '@/layouts/payment-method/payment-method-question/payment-method-question.vue';
import alert from '@/ux-components/alert/alert.vue';
import textBlock from '@/digital-components/text-block/text-block.vue';
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
import contactDetailsDrawer from '@/iss-components/contact-details-drawer/contact-details-drawer.vue';
import buttonMain from '@/ux-components/button-main/button-main.vue';

// Supporting Items
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { paymentMethods } from '@/constants/payment-method-constants';
import queryStrings from '@/constants/query-strings';
import globalRules from '@/constants/global-rules';
import { Form } from 'vee-validate';
import issPageValues from '@/router/router-constants/issPage-values';
import bailoutMessage from '@/constants/bailoutMessage';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
import { saveSession, submitWorkOrder } from '@/helpers/order-helper.js';
import { experimentSettings } from '@/constants/experiments';
import submitType from '@/constants/submit-type';
import routerParams from '@/router/router-constants/router-params';
import { supportsApplePay } from '@/helpers/browser-helper';
import { getCartTotal } from '@/helpers/cart-helper';
import { formatAmountInDollars } from '@/helpers/text-helper';
import widgetFields from '@/constants/cms-widget-fields';
import MaskaFormattedMasks from '@/constants/maska-masks';

export default {
    name: 'payment-method',
    components: {
        Form,
        siteHeader,
        siteSubHeader,
        siteFooter,
        reviewDropdown,
        cartDropdown,
        paymentMethodQuestion,
        alert,
        textBlock,
        buttonQuestion,
        textboxQuestion,
        contactDetailsDrawer,
        buttonMain
    },
    mixins: [baseFormMixin],
    async beforeRouteEnter(to, from, next) {
        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);

        const promiseResultMap = [
            {
                resultKey: 'cmsContent',
                promise: cmsContentPromise
            }
        ];

        const resultMap = await settleAllPromises(promiseResultMap);

        await useMainStore().setPriceAndSalesTaxForOrderLineItems();

        next((vm) => {
            vm.setCmsContent(resultMap.cmsContent);
            vm.initializeComponent();
            vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
        });
    },
    data() {
        return {
            paymentMethod: null,
            widget: {
                paymentMethod: 'PaymentMethodWidget',
                paymentMethodApplePay: 'PaymentMethodWidgetApplePay',
                amountDue: 'AmountDueCartHeaderTextWidget',
                payAtAppointment: 'PayAtAppointmentTextWidget',
                smsOptInHeader: 'SMSOptInHeaderWidget',
                smsOptInQuestion: 'SMSOptInQuestionWidget',
                smsPhoneNumber: 'SMSPhoneNumberWidget',
                smsDisclaimer: 'SMSDisclaimerWidget',
                wiperOffer: 'WiperOfferPanelWidget'
            },
            rules: {
                optionRequired: globalRules.OPTION_REQUIRED,
                phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}`
            },
            smsOptIn: '',
            smsPhoneNumber: ''
        };
    },
    computed: {
        customCallToActionButtonCopy() {
            switch (this.paymentMethod) {
                case paymentMethods.PayNow:
                case paymentMethods.AFTERPAY:
                    return 'Continue to checkout';
                default:
                    return null;
            }
        },
        displayPayInAdvanceAlert() {
            return this.$route.query[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT];
        },
        isPayInAdvanceDisabled() {
            const piaExperience = this.getSettingValue(experimentSettings.ISS_DISPLAY_PAY_IN_ADVANCE);
            const isEnabled = piaExperience === 'true';
            const isDeductibleTotalEqualToZero = useMainStore().currentDeductible === 0;

            return !isEnabled || useMainStore().isUnverified || (useMainStore().isDeductible && isDeductibleTotalEqualToZero);
        },
        paymentMethodWidgetName() {
            return supportsApplePay() ? this.widget.paymentMethodApplePay : this.widget.paymentMethod;
        },
        showCartTotal() {
            return this.mainStore.isVerified && (this.mainStore.isITAC || this.mainStore.isNoComp
            || this.mainStore.order.lineItems?.vaps?.length > 0);
        },
        cartHeaderText() {
            if (this.isPayInAdvanceDisabled) {
                return this.getCmsContent(
                    this.widget.payAtAppointment,
                    widgetFields.TEXT_BLOCK_WIDGET.TEXT
                );
            } else {
                return this.getCmsContent(
                    this.widget.amountDue,
                    widgetFields.TEXT_BLOCK_WIDGET.TEXT
                );
            }
        },
        cartTotal() {
            return formatAmountInDollars(getCartTotal(this.mainStore.order));
        },
        hideSMSOptIn() {
            return false;
        },
        smsOptInHeaderText() {
            return this.getCmsContent(
                this.widget.smsOptInHeader,
                widgetFields.TEXT_BLOCK_WIDGET.TEXT
            );
        },
        smsOptinQuestionText() {
            return this.getCmsContent(this.widget.smsOptInQuestion, widgetFields.INPUT_QUESTION_WIDGET.QUESTION_TEXT);
        },
        smsOptinQuestionAnswers() {
            return this.getCmsContent(this.widget.smsOptInQuestion, widgetFields.INPUT_QUESTION_WIDGET.ANSWERS) || [];
        },
        phoneMask() {
            return MaskaFormattedMasks.PHONE_NUMBER;
        },
        offerWipers() {
            return !this.mainStore.lineItems.vaps.some((part) => part.partType.toLowerCase().includes('wiper'));
        },
        wiperOfferPanel() {
            const wiperImage = this.getCmsContent(this.widget.wiperOffer, widgetFields.CONTENT_GROUP_WIDGET.IMAGE);
            const wiperHeader = this.getCmsContent(this.widget.wiperOffer, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT);
            const wiperBody = this.getCmsContent(this.widget.wiperOffer, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
            const wiperEdit = this.getCmsContent(this.widget.wiperOffer, widgetFields.CONTENT_GROUP_WIDGET.FOOTER_TEXT);

            return {
                image: wiperImage,
                header: wiperHeader,
                body: wiperBody,
                edit: wiperEdit
            }
        }
    },
    watch: {
        customCallToActionButtonCopy(newValue) {
            this.updateFooterButtonText(newValue);
        }
    },
    methods: {
        arePagePrerequisitesValid() {
            // Vehicle
            const { vehicle } = useMainStore().order;
            const vehicleReqs = !!(
                vehicle.year
                && vehicle.make
                && vehicle.model
                && vehicle.style
            );

            // Damage
            const { isRepair, numberOfChips, glassToReplace } =
                useMainStore().order.damage;
            const damageReqs = !!(
                (isRepair && numberOfChips)
                || (!isRepair && glassToReplace?.length)
            );

            // Service Package
            const { lineItems } = useMainStore().order;
            const packageReqs = !!(
                (isRepair || lineItems.glassParts)
                && lineItems.supportingItems
            );

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

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

            // Customer
            const { firstName, lastName, emailAddress } = useMainStore().order.customer;
            const customerReqs = !!(firstName && lastName && emailAddress);

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

            return (
                vehicleReqs
                && damageReqs
                && packageReqs
                && serviceLocationReqs
                && scheduleReqs
                && customerReqs
                && contactInfoReqs);
        },
        initializeComponent() {
            const paymentMethodFromStore = this.getPaymentMethodFromStore();
            // SMS Opt In defaults to 'no', but we don't actually want to use it if the user hasn't saved data form this page yet
            if (paymentMethodFromStore) {
                this.smsOptIn = this.getSMSOptInFromStore();
            }
            this.smsPhoneNumber = this.getSMSPhoneFromStore();
        },
        getPaymentMethodFromStore() {
            if (this.isPayInAdvanceDisabled) {
                return paymentMethods.PAY_AT_TIME_OF_SERVICE;
            }

            return useMainStore().order.payment.paymentMethod;
        },
        updateFooterButtonText(newValue) {
            this.$refs.siteFooter.updateButtonText(newValue);
        },
        async forwardButtonAction() {
            this.mainStore.savePaymentMethodChoice(this.paymentMethod);
            if (!this.hideSMSOptIn) {
                const requestTextUpdates = this.smsOptIn === 'Yes';
                this.mainStore.updateContactInfo({ requestTextUpdates });
                if (requestTextUpdates) {
                    this.mainStore.updatePhoneNumbers({ alternative: this.smsPhoneNumber, service: this.smsPhoneNumber });
                }
            }
            if (this.paymentMethod === paymentMethods.PAY_AT_TIME_OF_SERVICE) {
                try {
                    await submitWorkOrder({ submitType: submitType.SAFELITE });
                    this.$router.navigate(
                        this.navigationScenarios.CLICKED_FORWARD,
                        this.$route
                    );
                } catch (error) {
                    useMainStore().setBailout(bailoutMessage.saveSessionError(error.data));
                    this.$router.navigate(
                        this.navigationScenarios.SAVE_SESSION_FAILED,
                        this.$route,
                        { issPage: issPageValues.PAYMENT_METHOD }
                    );
                    console.error(`error: response from submit work order:${error.message}`);
                }
            } else {
                await saveSession({
                    createWorkOrderNumberForPIA: true,
                    shouldAwaitSaveSessionQueue: true
                });

                this.$router.navigate(
                    this.navigationScenarios.CLICKED_PAY_NOW,
                    this.$route,
                    {},
                    { [routerParams.SKIP_SAVE_SESSION]: true }
                );
            }
        },
        backButtonAction() {
            const scenario = this.mainStore.isMobileAppointment
                ? this.navigationScenarios.CLICKED_BACK_MOBILE
                : this.navigationScenarios.CLICKED_BACK_INSHOP;
            this.$router.navigateWithSpinner(
                scenario,
                this.$route
            );
        },
        getSMSOptInFromStore() {
            return this.mainStore.contactInfo.requestTextUpdates ? 'Yes' : 'No';
        },
        getSMSPhoneFromStore() {
            return this.mainStore.contactInfo.alternativePhone ?? this.mainStore.contactInfo.servicePhone;
        },
        handleEditClicked(section) {
            switch (section) {
                case 'location':
                    this.$router.navigateWithSpinner(
                        this.navigationScenarios.EDIT_SERVICE_LOCATION,
                        this.$route
                    );
                    break;
                case 'schedule':
                    this.$router.navigateWithSpinner(
                        this.navigationScenarios.EDIT_SCHEDULE,
                        this.$route
                    );
                    break;
                case 'vehicle':
                    this.$router.navigateWithSpinner(
                        this.navigationScenarios.EDIT_VEHICLE,
                        this.$route
                    );
                    break;
                case 'customer':
                    this.openContactDetailsModal();
                    break;
                case 'wipers':
                    this.$router.navigateWithSpinner(
                        this.navigationScenarios.EDIT_WIPERS,
                        this.$route
                    );
                    break;
            }
        },
        openContactDetailsModal() {
            this.$refs.contactDetailsDrawer.openModal();
        },
        refreshContactDetails() {
            this.smsPhoneNumber = this.mainStore.contactInfo.servicePhone;
        },
        closeContactDetailsWithoutSaving() {
            this.smsOptIn = 'No';
        }
    }
};
</script>

<style lang="scss" scoped>
$page-side-padding: 1.5rem;
#app .iss-heritage-container-width.payment-method-container {
    .alert-warning {
        margin-top: 1.25rem;
        margin-bottom: 0rem;
    }

    .subheader {
        margin-top: 1.25rem;

        :deep(strong) {
            color: $black;
            font-weight: 600;
        }

        :deep(.subheader-secondary) {
            margin-top: .625rem;

            p {
                margin-bottom: 0;
                color: #4d4e53;
            }
        }
    }

    .section-divider {
        margin-top: 1.5rem;
        margin-bottom: 1.875rem;
    }

    .cart-header {
        display: flex;
        align-items: center;
        gap: .25rem;
        margin-bottom: .625rem;

        .cart-label {
            color: $black;
            font-weight: $font-weight-bold;
        }

        .cart-value {
            color: $green;
            font-weight: $font-weight-bold;
            font-size: 1.625rem;
        }
    }

    .cart-dropdown-container {
        margin-bottom: 1.25rem;
    }

    .pia-divider {
        margin-top: .5rem;
        margin-bottom: 1.25rem;
    }

    .sms-divider {
        margin-top: 1.75rem;
        margin-bottom: 1.875rem;
    }

    .sms-opt-in-section {
        margin-bottom: 1.875rem;
    }

    .sms-opt-in-header {
        color: $black;
        font-weight: $font-weight-bold;
        margin-bottom: 1.125rem;
    }

    .sms-opt-in-question {
        margin-bottom: 1.25rem;

        :deep(.question-text) {
            margin-bottom: .625rem;
        }
    }

    .disclaimer {
        margin-bottom: 1.875rem;
        font-weight: $font-weight-light;
        font-size: .8125rem;
        line-height: 1.54;
        color: #4d4e53;

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

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

    .contact-details-drawer {
        :deep(strong) {
            color: $black;
            font-weight: 600;
        }
    }

    .wiper-offer-panel {
        margin-top: 1.25rem;
        margin-bottom: 1.375rem;
        box-shadow: 0 0 .625rem 1px #cacbcc;
        border: 1px solid #ddd;
        border-radius: .25rem;
        max-height: fit-content;

        .wiper-logo {
            margin: 1.25rem 2.25rem 0 2.25rem;
            img {
                max-width: 100%;
                height: auto;
            }
        }

        .panel-body {
            padding: 0 1rem 1.25rem 1rem;

            .wiper-header {
                margin: 1.25rem 0 .625rem 0;
                color: $black;
                font-weight: $font-weight-bold;
            }
        }

        .panel-footer {
            padding: 0 1rem 1.25rem 1rem;

            .edit-wiper-offer-button {
                width: 100%;
            }
        }
    }
}
</style>
