<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">
                <div class="payment-method-container iss-heritage-content-container-width">
                    <siteSubHeader
                        class="mb-5 mt-4 px-3"
                        cmsWidgetName="SiteSubHeaderWidget"
                        secondaryTextClasses="text-center"
                        subHeaderClasses="mt-4" />
                    <div class="main-content-container">
                        <hr class="my-0" />
                        <reviewDropdown ref="reviewDropdown" />
                        <hr class="my-0" />
                        <cartDropdown
                            :showAsPaid="false"
                            :readOnly="false"
                            recyclingModalCmsWidgetName="RecycleModal"
                            servicePackageTitleWidgetName="ServicePackageTitle" />
                        <hr class="mt-0 mb-5" />
                        <alert
                            v-if="displayPayInAdvanceAlert"
                            name="payInAdvanceErrorAlert"
                            class="my-4"
                            cmsWidgetName="PayInAdvanceErrorAlertWidget"
                            alertClass="alert-danger"
                            :isDismissible="false" />
                        <paymentMethodQuestion
                            v-if="!isPayInAdvanceDisabled"
                            v-model="paymentMethod"
                            :cmsWidgetName="paymentMethodWidgetName"
                            :validationRules="rules.optionRequired" />
                        <alert
                            v-if="isPayInAdvanceDisabled"
                            :isDismissible="false"
                            alertClass="alert-info"
                            cmsWidgetName="NoPayInAdvanceDisclaimerWidget"
                            :shouldScrollToOnMount="false" />
                        <siteFooter
                            ref="siteFooter"
                            cmsWidgetName="SiteFooterWidget"
                            :isForwardActionDisabled="!meta.valid"
                            :isStackedVertically="true"
                            @backClicked="backButtonAction"
                            @ForwardClicked="forwardButtonAction" />
                    </div>
                </div>
            </div>
        </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';

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

export default {
    name: 'payment-method',
    components: {
        // eslint-disable-next-line vue/no-reserved-component-names
        Form,
        siteHeader,
        siteSubHeader,
        siteFooter,
        reviewDropdown,
        cartDropdown,
        paymentMethodQuestion,
        alert
    },
    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'
            },
            rules: {
                optionRequired: globalRules.OPTION_REQUIRED
            }
        };
    },
    computed: {
        customCallToActionButtonCopy() {
            switch (this.paymentMethod) {
                case paymentMethods.PayNow:
                    return 'Continue to checkout';
                case paymentMethods.AFTERPAY:
                    return 'Continue to Afterpay';
                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;
        }
    },
    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() {
            this.paymentMethod = this.getPaymentMethodFromStore();
        },
        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() {
            useMainStore().savePaymentMethodChoice(this.paymentMethod);
            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.navigate(
                scenario,
                this.$route
            );
        }
    }
};
</script>

<style lang="scss" scoped>
$page-side-padding: 1.5rem;
.iss-heritage-container-width {
    .payment-method-container {
        position: relative;
        min-height: 1px;
        padding-left: .9375rem;
        padding-right: .9375rem;
    }
}

.main-content-container {
    padding: 0;
}

.page-container-grouped-styles {
    overflow: auto;
}
</style>
