<template>
    <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
        <funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
        <div class="container vehicle">
            <div class="row">
                <div class="col-12 col-md-10 col-lg-8 col-xl-7">
                    <funnelSubHeader
                        cmsWidgetName="FunnelSubHeaderWidget"
                        class="siteSubHeader"
                        :alignLeft="true" />
                    <vehicleQuestion
                        ref="vehicleYearQuestion"
                        v-model="selectedYear"
                        :isDisabled="isYearDisabled"
                        :options="yearOptions"
                        cmsWidgetName="VehicleYearQuestion"
                        validationRules="year-required"
                        placeHolderText="Select year"
                        customDropdownId="yearQuestionField" />

                    <vehicleQuestion
                        ref="vehicleMakeQuestion"
                        v-model="selectedMake"
                        :isDisabled="isMakeDisabled"
                        :options="makeOptions"
                        cmsWidgetName="VehicleMakeQuestion"
                        validationRules="make-required"
                        placeHolderText="Select make"
                        customDropdownId="makeQuestionField" />

                    <vehicleQuestion
                        ref="vehicleModelQuestion"
                        v-model="selectedModel"
                        cmsWidgetName="VehicleModelQuestion"
                        :isDisabled="isModelDisabled"
                        :options="modelOptions"
                        validationRules="model-required"
                        placeHolderText="Select model"
                        customDropdownId="modelQuestionField" />

                    <vehicleQuestion
                        ref="vehicleStyleQuestion"
                        v-model="selectedStyle"
                        cmsWidgetName="VehicleStyleQuestion"
                        :isDisabled="isStyleDisabled"
                        :options="styleOptions"
                        validationRules="style-required"
                        placeHolderText="Select style"
                        customDropdownId="styleQuestionField" />

                    <div v-if="isBigTruckAndCanService">
                        <div class="separator-line"></div>
                        <textboxQuestion
                            class="mb-4"
                            cmsWidgetName="ServiceZipQuestionWidget"
                            v-model="serviceZipCode"
                            inputId="serviceZipCode"
                            mask="#####"
                            isRequired
                            validationRules="zip-required|zip-format" />
                    </div>

                    <alert
                        ref="AlertNoService"
                        v-if="displayNoServiceAlert"
                        class="mt-4 alert"
                        cmsWidgetName="AlertNoServiceWidget"
                        alertClass="alert-danger"
                        :isDismissible="false" />

                    <navbar
                        cmsWidgetName="FunnelFooterWidget"
                        @ForwardClicked="forwardButtonAction"
                        :isForwardActionDisabled="
                            !meta.valid || !allDataRetrieved || displayNoServiceAlert
                        "
                        ref="navbar" />
                </div>
            </div>
        </div>
    </Form>
</template>

<script>
// Components
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 vehicleQuestion from "@/layouts/vehicle/vehicle-question/vehicle-question";
import textboxQuestion from "@/digital-components/textbox-question/textbox-question";

// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { experimentUniverses } from "@/constants/experiments";
import {
    getSessionKeyValue,
    getUserIdValue,
    getDeviceIdValue,
} from "@/helpers/heritage-integration/cookie-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import { Form, defineRule } from "vee-validate";
import { required, regex } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
import store from "@/store";
import { storeActions } from "@/constants/store-actions.js";
import baseMixin from "@/mixins/base-mixin.js";
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
import { applicationConfig } from "../../constants/application-config";
import { queryStrings } from "@/constants/query-strings";
import { getQuerystringParameter } from "@/helpers/querystring-helper";
import { debugLog } from "@/helpers/debug-log-helper";

//define validation rules
defineRule("year-required", required(errorMessages.YEAR_REQUIRED));
defineRule("make-required", required(errorMessages.MAKE_REQUIRED));
defineRule("model-required", required(errorMessages.MODEL_REQUIRED));
defineRule("style-required", required(errorMessages.STYLE_REQUIRED));
defineRule("zip-required", required(errorMessages.ZIP_REQUIRED));
defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.ZIP_FORMAT));

export default {
    name: "vehicle",
    data() {
        return {
            selectedYear: this.selectedYearfromStore(),
            selectedMake: this.selectedMakefromStore(),
            selectedModel: this.selectedModelfromStore(),
            selectedStyle: this.selectedStylefromStore(),
            carId: this.getCarIdfromStore(),
            category: this.getCategoryfromStore(),
            isBigTruck: this.getIsBigTruckfromStore(),
            imageUrl: this.getImagefromStore(),
            imageVifNumber: this.getImageVifNumberfromStore(),
            imageVifColor: this.getImageVifColorfromStore(),
            serviceZipCode: this.getZipFromStore(),
            yearOptions: [],
            makeOptions: [],
            modelOptions: [],
            styleOptions: [],
            displayNoServiceAlert: false,
            canSafeliteService: this.canSafeliteServiceFromStore(),
        };
    },

    async beforeRouteEnter(to, from, next) {
        debugLog("------------- vehicle.vue applicationConfig start -------------");
        debugLog("", applicationConfig);
        debugLog("------------- vehicle.vue applicationConfig end -------------");

        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to.name);
        const experimentForLogging = store.getters.applicationUser.experiments.find(
            (e) => e.universeName === experimentUniverses.CONCEPT_FUNNEL
        );
        const yearQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.GET_VEHICLE_YEARS,
            {},
            "vehicle"
        );
        var makeQuestionInitialDataPromise = null;
        var modelQuestionInitialDataPromise = null;
        var styleQuestionInitialDataPromise = null;
        const year =
            store.getters.externalParameterVehicle.year || store.getters.order.vehicle.year;
        const make =
            store.getters.externalParameterVehicle.make || store.getters.order.vehicle.make;
        const model =
            store.getters.externalParameterVehicle.model || store.getters.order.vehicle.model;
        const style =
            store.getters.externalParameterVehicle.style || store.getters.order.vehicle.style;

        if (make && model && style) {
            makeQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.GET_VEHICLE_MAKES,
                {
                    year: year,
                },
                "vehicle"
            );

            modelQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.GET_VEHICLE_MODELS,
                {
                    year: year,
                    make: make,
                },
                "vehicle"
            );

            styleQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.GET_VEHICLE_STYLES,
                {
                    year: year,
                    make: make,
                    model: model,
                },
                "vehicle"
            );
        }

        // If the concept funnel experiment is found, as it should be when coming from safelite.com, then log the experiment exposure.
        if (experimentForLogging !== undefined) {
            // Log experiment exposure
            baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.LOG_EXPERIMENT_EXPOSURE_AND_UPDATE_STORE,
                {
                    userId: getUserIdValue(),
                    deviceId: getDeviceIdValue(),
                    sessionKey: getSessionKeyValue(),
                    pageName: to.name,
                    experiment: experimentForLogging,
                },
                "vehicle",
                false
            );
        }

        // Settle promises and get results
        const promiseResultMap = [
            {
                resultKey: "cmsContent",
                promise: cmsContentPromise,
            },
            {
                resultKey: "yearQuestionInitialData",
                promise: yearQuestionInitialDataPromise,
            },
            {
                resultKey: "makeQuestionInitialData",
                promise: makeQuestionInitialDataPromise,
            },
            {
                resultKey: "modelQuestionInitialData",
                promise: modelQuestionInitialDataPromise,
            },
            {
                resultKey: "styleQuestionInitialData",
                promise: styleQuestionInitialDataPromise,
            },
        ];

        let resultMap = await settleAllPromises(promiseResultMap);

        //ExternalParameter widget have different case style value so need to parse with NextGen
        if (store.getters.externalParameterState?.isExternalParameter) {
            if (
                makeQuestionInitialDataPromise &&
                modelQuestionInitialDataPromise &&
                styleQuestionInitialDataPromise
            ) {
                const matchingMake = resultMap.makeQuestionInitialData?.filter(
                    (item) =>
                        item.toLowerCase() ===
                        store.getters.externalParameterVehicle.make.toLowerCase()
                );
                const matchingModel = resultMap.modelQuestionInitialData?.filter(
                    (item) =>
                        item.toLowerCase() ===
                        store.getters.externalParameterVehicle.model.toLowerCase()
                );
                const matchingStyle = resultMap.styleQuestionInitialData?.filter(
                    (item) =>
                        item.toLowerCase() ===
                        store.getters.externalParameterVehicle.style.toLowerCase()
                );
                baseMixin.methods.dispatchStoreAction(
                    storeActions.UPDATE_EXTERNAL_PARAMETER_MMS,
                    {
                        externalParameterMake: matchingMake[0],
                        externalParameterModel: matchingModel[0],
                        externalParameterStyle: matchingStyle[0],
                    },
                    false
                );
            }
        }

        // Call the "next" function to complete the transition to this page.
        next(async (vm) => {
            vm.setCmsContent(resultMap.cmsContent);
            vm.initializeYearComponent(resultMap.yearQuestionInitialData);

            if (
                makeQuestionInitialDataPromise &&
                modelQuestionInitialDataPromise &&
                styleQuestionInitialDataPromise
            )
                vm.initializeMMSComponent(
                    resultMap.makeQuestionInitialData,
                    resultMap.modelQuestionInitialData,
                    resultMap.styleQuestionInitialData
                );
            if (store.getters.externalParameterState?.isExternalParameter) {
                await vm.getVehicleDetails();
                if (!vm.displayNoServiceAlert) {
                    const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm);
                    if (isValid) {
                        vm.forwardButtonAction();
                    } else {
                        baseMixin.methods.ResetExternalParamsAndHideModal();
                    }
                } else {
                    baseMixin.methods.ResetExternalParamsAndHideModal();
                }
            } else {
                baseMixin.methods.ResetExternalParamsAndHideModal();
            }
        });
    },

    watch: {
        serviceZipCode(newValue, oldValue) {
            this.resetAlert();
        },
        async selectedYear(year) {
            this.resetAlert();
            this.makeOptions = [];
            this.selectedMake = null;
            this.selectedModel = null;
            this.selectedStyle = null;
            this.isBigTruck = false;
            this.canSafeliteService = false;
            this.carId = null;
            if (year) {
                const result = await this.getMakeOptions(year);
                if (this.selectedYear == year) {
                    this.makeOptions = result?.data;
                    if (this.selectedYearfromStore() !== year) {
                        this.selectedMake = null;
                        this.selectedModel = null;
                        this.selectedStyle = null;
                        this.carId = null;
                    }
                }
            }
        },
        async selectedMake(make) {
            this.resetAlert();
            this.modelOptions = [];
            this.selectedModel = null;
            this.selectedStyle = null;
            this.isBigTruck = null;
            this.carId = null;
            if (make) {
                const result = await this.getModelOptions(this.selectedYear, make);
                if (this.selectedMake == make) {
                    this.modelOptions = result?.data;
                    if (this.modelOptions.length === 1) this.selectedModel = this.modelOptions[0];
                    else {
                        this.selectedModel = null;
                        this.selectedStyle = null;
                        this.carId = null;
                    }
                }
            }
        },
        async selectedModel(model) {
            this.resetAlert();
            this.styleOptions = [];
            this.selectedStyle = null;
            this.isBigTruck = false;
            this.carId = null;
            if (model) {
                const result = await this.getStyleOptions(
                    this.selectedYear,
                    this.selectedMake,
                    model
                );
                if (this.selectedModel == model) {
                    this.styleOptions = result?.data;
                    if (this.styleOptions.length === 1) {
                        const sameStyle = this.selectedStyle === this.styleOptions[0];
                        this.selectedStyle = this.styleOptions[0];
                        if (sameStyle) {
                            this.getVehicleDetails();
                        }
                    } else {
                        this.selectedStyle = null;
                        this.carId = null;
                    }
                }
            }
        },
        async selectedStyle(style) {
            this.resetAlert();
            if (style) {
                this.getVehicleDetails();
            } else {
                this.imageUrl = null;
                this.carId = null;
            }
        },
    },
    computed: {
        isYearDisabled() {
            return this.isDisabled(this.yearOptions);
        },
        isMakeDisabled() {
            return this.isDisabled(this.makeOptions);
        },
        isModelDisabled() {
            return this.isDisabled(this.modelOptions);
        },
        isStyleDisabled() {
            return this.isDisabled(this.styleOptions);
        },
        unmatchedVehicleIcon() {
            if (this.imageUrl == null && this.carId !== null) return true;
            else return false;
        },
        displayGeneric() {
            if (!this.selectedStyle) return true;
            else if (this.carId == null) return true;
            else if (this.imageUrl == null && this.carId !== null) return false;
            else return true;
        },
        allDataRetrieved() {
            return (
                !!this.selectedYear &&
                !!this.selectedMake &&
                !!this.selectedModel &&
                !!this.selectedStyle &&
                !!this.carId
            );
        },
        isBigTruckAndCanService() {
            return this.isBigTruck && this.canSafeliteService;
        },
    },
    methods: {
        getZipFromStore() {
            return (
                store.getters?.externalParameterServiceZip?.zipCode ??
                store.getters.order?.serviceLocation?.zipCode
            );
        },
        isDisabled(options) {
            if (
                !options.length ||
                store.getters.payment?.insuranceCoverage?.isVerified ||
                (store.getters.order.payment?.isInsurance &&
                    getFunnelCookie()?.HasDelayedClaimRegistration)
            ) {
                return true;
            } else {
                return false;
            }
        },
        getVehicle(year, make, model, style) {
            return this.dispatchStoreActionWithLogging(
                this.storeActions.GET_VEHICLE,
                {
                    year: year,
                    make: make,
                    model: model,
                    style: style,
                },
                "vehicle"
            );
        },
        arePagePrerequisitesValid() {
            return true;
        },
        async getVehicleDetails() {
            this.carId = null;
            const result = await this.getVehicle(
                this.selectedYear,
                this.selectedMake,
                this.selectedModel,
                this.selectedStyle
            );
            this.carId = result?.data.carId;
            this.category = result?.data.category;
            this.imageUrl = result?.data.imageUrl;
            this.imageVifNumber = result?.data.imageVifNumber;
            this.imageVifColor = result?.data.imageVifColor;
            this.displayNoServiceAlert = !result?.data.canSafeliteService;
            this.canSafeliteService = result?.data.canSafeliteService;
            this.vehicleSubType = result?.data.vehicleSubType;
            this.vehicleSpecialClass = result?.data.vehicleSpecialClass;
            this.isBigTruck = result?.data.isBigTruck;
        },
        resetAlert() {
            this.displayNoServiceAlert = false;
        },
        async forwardButtonAction() {
            await this.dispatchStoreAction(storeActions.RESET_SUBMITTED_STATE);
            let zipCodeData;
            if (this.isBigTruck) {
                zipCodeData = await this.getZipCodeData(this.serviceZipCode);

                // check the location endpoint to verify this zip can service a heavy truck
                var closestShops = await this.dispatchStoreActionWithLogging(
                    storeActions.GET_CLOSEST_APPLICABLE_SHOPS,
                    { zip: this.serviceZipCode, carId: this.carId },
                    "vehicle"
                );
                if (
                    !closestShops?.data?.inShopProviders ||
                    closestShops.data.inShopProviders.length === 0
                ) {
                    this.displayNoServiceAlert = true;
                    if (store.getters.externalParameterState?.isExternalParameter) {
                        return baseMixin.methods.ResetExternalParamsAndHideModal();
                    }
                    return this.$refs.navbar.removeLoader();
                }
            }

            if (zipCodeData) {
                await this.dispatchStoreAction(
                    storeActions.SAVE_SERVICE_ZIP_CODE_INFO,
                    {
                        zipCode: this.serviceZipCode,
                        state: zipCodeData.state,
                        zipCodeCtu: zipCodeData.zipCodeCtu,
                    },
                    false
                );
            }

            this.dispatchStoreAction(
                storeActions.SAVE_VEHICLE,
                {
                    year: this.selectedYear,
                    make: this.selectedMake,
                    model: this.selectedModel,
                    style: this.selectedStyle,
                    vehicleSubType: this.vehicleSubType,
                    vehicleSpecialClass: this.vehicleSpecialClass,
                    isBigTruck: this.isBigTruck,
                    carId: this.carId,
                    category: this.category,
                    canSafeliteService: this.canSafeliteService,
                    imageUrl: this.imageUrl,
                    imageVifNumber: this.imageVifNumber,
                    imageVifColor: this.imageVifColor,
                },
                false
            );

            this.$router.navigateWithSaving(
                this.navigationScenarios.CLICKED_FORWARD,
                this.pageName
            );
        },
        initializeYearComponent(initialData) {
            this.yearOptions = initialData;
        },
        initializeMMSComponent(makeOptions, modelOptions, styleOptions) {
            this.makeOptions = makeOptions;
            this.modelOptions = modelOptions;
            this.styleOptions = styleOptions;
        },
        selectedYearfromStore() {
            return (
                store.getters.externalParameterVehicle.year ??
                store.getters.vehicle.year?.toString()
            );
        },
        selectedMakefromStore() {
            return store.getters.externalParameterVehicle.make ?? store.getters.vehicle.make;
        },
        selectedModelfromStore() {
            return store.getters.externalParameterVehicle.model ?? store.getters.vehicle.model;
        },
        selectedStylefromStore() {
            return store.getters.externalParameterVehicle.style ?? store.getters.vehicle.style;
        },
        canSafeliteServiceFromStore() {
            return store.getters.vehicle.canSafeliteService ?? false;
        },
        async getMakeOptions(year) {
            return await baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.GET_VEHICLE_MAKES,
                {
                    year: year,
                },
                "vehicle"
            );
        },

        async getModelOptions(year, make) {
            return await baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.GET_VEHICLE_MODELS,
                {
                    year: year,
                    make: make,
                },
                "vehicle"
            );
        },

        async getStyleOptions(year, make, model) {
            return await baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.GET_VEHICLE_STYLES,
                {
                    year: year,
                    make: make,
                    model: model,
                },
                "vehicle"
            );
        },
        getImagefromStore() {
            return store.getters.vehicle.imageUrl;
        },
        getCarIdfromStore() {
            return store.getters.vehicle.carId;
        },
        getCategoryfromStore() {
            return store.getters.vehicle.category;
        },
        getImageVifNumberfromStore() {
            return store.getters.vehicle.imageVifNumber;
        },
        getImageVifColorfromStore() {
            return store.getters.vehicle.imageVifColor;
        },
        getIsBigTruckfromStore() {
            return store.getters.vehicle.isBigTruck;
        },
    },

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

<style lang="scss">
.vehicle-footer {
    margin-bottom: 0;
}
.siteSubHeader {
    margin: 0;
}
.separator-line {
    grid-area: 2/1/2/8;
    border-top: 1px solid $gray-500;
    margin: 0.5rem 0;
}
</style>
