<template>
    <Form
        ref="theForm"
        v-slot="{ meta }"
        @submit="onSubmit"
        @invalidSubmit="onInvalidSubmit">
        <div class="container-fluid fade-on-route-transition">
            <div class="row justify-content-center">
                <div class="col-md-6 px-0 px-md-2">
                    <siteHeader
                        ref="siteHeader"
                        cmsWidgetName="SiteHeaderWidget" />
                </div>
            </div>
            <div class="row justify-content-center">
                <div class="col-md-6 col-xl-4">
                    <vehicleBanner
                        cmsWidgetName="VehicleBannerWidget"
                        :displayGenericVehicleImage="false" />
                    <siteSubHeader
                        class="mb-5 mt-4 px-3"
                        cmsWidgetName="SiteSubHeaderWidget"
                        subHeaderClasses="mt-2" />
                    <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"
                            :availableVaps="availableVaps" />
                        <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="paymentMethodInternalModel"
                            cmsWidgetName="PaymentMethodWidget"
                            :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="navigateBack"
                            @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 { experimentSettings } from '@/constants/experiments';
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';

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 reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
        const wipersPromise = useMainStore().getWipers();
        const rainDefensePromise = useMainStore().getRainDefense();

        const promiseResultMap = [
            {
                resultKey: 'cmsContent',
                promise: cmsContentPromise,
            },
            {
                resultKey: 'reviewDropdownData',
                promise: reviewDropdownPromise,
            },
            {
                resultKey: 'wipers',
                promise: wipersPromise,
            },
            {
                resultKey: 'rainDefense',
                promise: rainDefensePromise,
            },
        ];

        const resultMap = await settleAllPromises(promiseResultMap);

        await useMainStore().setPriceAndSalesTaxForOrderLineItems();

        const unpricedVaps = [...resultMap.wipers, resultMap.rainDefense];

        let hasBailedOut = false;
        const pricedVaps = await useMainStore()
            .getPriceOrderItems(unpricedVaps)
            .catch((err) => {
                useMainStore().setBailout(
                    bailoutMessage.pricingResponseError(
                        unpricedVaps.map((li) => li.partNumber),
                        { code: err.code, message: err.message, data: err.data }
                    )
                );
                hasBailedOut = true;
                next(`/?issPage=${issPageValues.BAILOUT_PAGE}`);
            });

        if (!hasBailedOut) {
            next((vm) => {
                vm.setCmsContent(resultMap.cmsContent);
                vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
                vm.$refs.reviewDropdown.initializeComponent(
                    resultMap.reviewDropdownData
                );
                vm.setAvailableVaps(pricedVaps ?? []);
            });
        }
    },
    data() {
        return {
            availableVaps: [],
            paymentMethodInternalModel: this.getPaymentMethodFromStore(),
            rules: {
                optionRequired: globalRules.OPTION_REQUIRED,
            },
        };
    },
    computed: {
        customCallToActionButtonCopy() {
            switch (this.paymentMethod) {
                case paymentMethods.CREDIT_CARD:
                    return 'Continue to checkout';
                case paymentMethods.PAYPAL:
                    return 'Continue to Paypal';
                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';

            return !isEnabled || this.isUnverified;
        },
        isUnverified() {
            return (
                !useMainStore().isNoComp &&
                !useMainStore().isITAC &&
                (useMainStore().order.currentDeductible == null ||
                    !useMainStore().isVerifiedCoverageStatus)
            );
        },
        paymentMethod() {
            return this.paymentMethodInternalModel;
        },
    },
    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().order;
            const contactInfoReqs = !!(
                contactInfo.firstName &&
                contactInfo.lastName &&
                contactInfo.servicePhone &&
                contactInfo.emailAddress
            );

            return (
                vehicleReqs &&
                damageReqs &&
                packageReqs &&
                serviceLocationReqs &&
                scheduleReqs &&
                customerReqs &&
                contactInfoReqs
            );
        },
        getPaymentMethodFromStore() {
            const { payInAdvanceType } = useMainStore().order.payment;
            const isPayInAdvance =
                useMainStore().order.payment.isPayInAdvance &&
                !!payInAdvanceType;

            return isPayInAdvance
                ? payInAdvanceType
                : paymentMethods.PAY_AT_TIME_OF_SERVICE;
        },
        updateFooterButtonText(newValue) {
            this.$refs.siteFooter.updateButtonText(newValue);
        },
        async forwardButtonAction() {
            await useMainStore().savePaymentMethodChoice(this.paymentMethod);

            if (this.paymentMethod === paymentMethods.PAY_AT_TIME_OF_SERVICE) {
                this.$router.navigate(
                    this.navigationScenarios.CLICKED_FORWARD,
                    this.$route
                );
            } else {
                this.$router.navigate(
                    this.navigationScenarios.CLICKED_PAY_NOW,
                    this.$route
                );
            }
        },
        setAvailableVaps(vaps) {
            this.availableVaps = vaps;
        },
    },
};
</script>

<style lang="scss" scoped>
$page-side-padding: 1.5rem;

.page-container-grouped-styles {
    overflow: auto;

    .main-content-container {
        padding: 0 1.5rem !important;
    }
}
</style>
