<template>
    <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
        <funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
        <div class="container ymm-return">
            <div class="row">
                <div class="col-12 col-md-10 col-lg-8 col-xl-7">
                    <funnelSubHeader
                        class="mb-5"
                        :cmsWidgetName="getSubHeaderWidget"
                        :alignLeft="true" />

                    <textboxQuestion
                        isRequired
                        class="mb-4"
                        cmsWidgetName="FirstNameQuestionWidget"
                        v-model="firstName"
                        ref="firstName"
                        customInputId="firstName"
                        validationRules="first-name-required" />

                    <textboxQuestion
                        isRequired
                        class="mb-4"
                        cmsWidgetName="LastNameQuestionWidget"
                        v-model="lastName"
                        ref="lastName"
                        customInputId="lastName"
                        validationRules="last-name-required" />

                    <textboxQuestion
                        isRequired
                        class="mb-4"
                        cmsWidgetName="EmailQuestionWidget"
                        v-model="emailAddress"
                        inputId="email"
                        validationRules="email-address-required|email-address-format" />

                    <phoneNumberQuestion
                        isRequired
                        class="mb-4"
                        cmsWidgetName="PhoneNumberQuestionWidget"
                        v-model="phoneNumber"
                        validationRules="phone-number-required" />

                    <textboxQuestion
                        isRequired
                        v-if="!serviceZipCode"
                        class="mb-4"
                        cmsWidgetName="ServiceZipQuestionWidget"
                        v-model="serviceZipCode"
                        ref="serviceZip"
                        customInputId="serviceZip"
                        mask="#####"
                        validationRules="service-zip-required|service-zip-format" />

                    <alert
                        ref="alertInvalidZip"
                        v-if="displayInvalidZipAlert"
                        class="mb-4"
                        cmsWidgetName="AlertInvalidZipWidget"
                        alertClass="alert-danger"
                        v-bind:isDismissible="false" />

                    <checkboxQuestion
                        class="mb-5"
                        cmsWidgetName="TextMeQuestionWidget"
                        v-model="isSmsOptIn" />

                    <navbar
                        cmsWidgetName="FunnelFooterWidget"
                        ref="navbar"
                        :isForwardActionDisabled="!meta.valid"
                        @back-clicked="backButtonAction"
                        @ForwardClicked="forwardButtonAction" />

                    <textBlock
                        class="mb-5"
                        cmsWidgetName="DisclaimerCopyWidget"
                        typeStyle="caption" />
                </div>
            </div>
        </div>
    </Form>
</template>

<script>
import { Form, defineRule } from "vee-validate";
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import navbar from "@/fmg-components/nav-bar/nav-bar";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import alert from "@/ux-components/alert/alert";
import textboxQuestion from "@/digital-components/textbox-question/textbox-question";
import phoneNumberQuestion from "@/digital-components/phone-number-question/phone-number-question";
import textBlock from "@/digital-components/text-block/text-block";
import checkboxQuestion from "@/digital-components/checkbox-question/checkbox-question";
import { routeData } from "@/router/constants/routes";
import { bailoutCodes } from "@/constants/bailout-codes";

import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";

import store from "@/store";
import { errorMessages } from "@/constants/error-messages";
import { required, regex } from "@/helpers/validation-rules";

// DEFINE VALIDATION RULES
defineRule("first-name-required", required(errorMessages.FIRST_NAME_REQUIRED));
defineRule("last-name-required", required(errorMessages.LAST_NAME_REQUIRED));
defineRule("phone-number-required", required(errorMessages.PHONE_REQUIRED));
defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule(
    "email-address-format",
    regex(
        /^([a-zA-Z0-9_.+]+)@([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*\.)+([a-zA-Z]{2,})$/,
        errorMessages.EMAIL_ADDRESS_FORMAT
    )
);
defineRule("service-zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
defineRule(
    "service-zip-format",
    regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT)
);

export default {
    name: "bailout",
    mixins: [],
    data() {
        return {
            bailoutCode: this.getBailoutCodeFromStore(),
            firstName: this.getFirstNameFromStore(),
            lastName: this.getLastNameFromStore(),
            emailAddress: this.getEmailAddressFromStore(),
            phoneNumber: this.getPhoneNumberFromStore(),
            serviceZipCode: this.getServiceZipFromStore(),
            isSmsOptIn: this.getIsSmsOptInFromStore(),
            displayInvalidZipAlert: false,
        };
    },

    async beforeRouteEnter(to, from, next) {
        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to.name);

        // Settle API calls in parallel before handling results.
        const promiseResultMap = [
            {
                resultKey: "cmsContent",
                promise: cmsContentPromise,
            },
        ];

        const resultMap = await settleAllPromises(promiseResultMap);

        // Hydrate page with results
        next(async (vm) => {
            vm.setCmsContent(resultMap.cmsContent);
        });
    },

    methods: {
        getBailoutCodeFromStore() {
            return store.getters.applicationUser.bailoutCode;
        },
        getFirstNameFromStore() {
            return store.getters.order.customer.firstName;
        },
        getLastNameFromStore() {
            return store.getters.order.customer.lastName;
        },
        getEmailAddressFromStore() {
            return store.getters.order.customer.emailAddress;
        },
        getPhoneNumberFromStore() {
            return store.getters.order.customer.phoneNumber;
        },
        getServiceZipFromStore() {
            return store.getters.order.serviceLocation.zipCode;
        },
        getIsSmsOptInFromStore() {
            return store.getters.order.customer.isSmsOptIn;
        },
        async backButtonAction() {
            this.$router.go(-1);
        },
        async forwardButtonAction() {
            this.displayInvalidZipAlert = false;

            const validateZipResponse = this.dispatchStoreActionWithLogging(
                this.storeActions.VALIDATE_ZIP,
                {
                    zip: this.serviceZipCode,
                },
                this.pageName
            );

            const saveCustomerDetailsResponse = this.dispatchStoreAction(
                this.storeActions.SAVE_CUSTOMER_DETAILS,
                {
                    firstName: this.firstName,
                    lastName: this.lastName,
                    emailAddress: this.emailAddress,
                    phoneNumber: this.phoneNumber,
                    isSmsOptIn: this.isSmsOptIn,
                },
                false
            );

            const promiseResultMap = [
                {
                    resultKey: "validateZipResponse",
                    promise: validateZipResponse,
                },
                {
                    resultKey: "saveCustomerDetailsResponse",
                    promise: saveCustomerDetailsResponse,
                },
            ];

            const resultMap = await settleAllPromises(promiseResultMap);
            const isZipValid = resultMap.validateZipResponse.isValid;

            if (isZipValid) {
                await this.dispatchStoreActionWithLogging(
                    this.storeActions.SAVE_SERVICE_ZIP_CODE_INFO,
                    {
                        zipCode: this.serviceZipCode,
                        state: resultMap.validateZipResponse.state,
                        zipCodeCtu: resultMap.validateZipResponse.zipCodeCtu,
                    },
                    false
                ).then(() => {
                    this.$router.navigateWithPageData(
                        this.navigationScenarios.CLICKED_FORWARD,
                        this.pageName,
                        {
                            bailoutCode: this.bailoutCode,
                            submit: true,
                        }
                    );
                });
            } else {
                this.displayInvalidZipAlert = true;
                return this.$refs.navbar.removeLoader();
            }
        },
        arePagePrerequisitesValid() {
            return this.getBailoutCodeFromStore() !== null;
        },
    },

    computed: {
        getSubHeaderWidget() {
            switch (this.bailoutCode) {
                case bailoutCodes.PART_NOT_FOUND:
                    return "PartsNotFoundSubHeaderWidget";
                default:
                    return "FunnelSubHeaderWidget";
            }
        },
    },

    components: {
        Form,
        funnelHeader,
        funnelSubHeader,
        alert,
        navbar,
        textBlock,
        phoneNumberQuestion,
        checkboxQuestion,
        textboxQuestion,
    },
};
</script>
