<template>
    <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
        <div class="container-fluid">
            <div class="row justify-content-center">
                <div class="col-md-6">
                    <funnelHeader cmsWidgetName="FunnelHeaderWidget" />
                </div>
            </div>
            <div class="row justify-content-center">
                <div class="col-md-6 col-xl-4">
                    <funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="siteSubHeader" />
                    <vehicleQuestion
                        ref="vehicleYearQuestion"
                        v-model="selectedYear"
                        :isDisabled="!yearOptions.length"
                        :options="yearOptions"
                        cmsWidgetName="VehicleYearQuestion"
                        validationRules="year-required"
                        placeHolderText="Select year"
                        inputId="yearQuestionField" />

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

                    <vehicleQuestion
                        ref="vehicleModelQuestion"
                        v-model="selectedModel"
                        cmsWidgetName="VehicleModelQuestion"
                        :isDisabled="!modelOptions.length"
                        :options="modelOptions"
                        validationRules="model-required"
                        placeHolderText="Select model"
                        inputId="modelQuestionField" />

                    <vehicleQuestion
                        ref="vehicleStyleQuestion"
                        v-model="selectedStyle"
                        cmsWidgetName="VehicleStyleQuestion"
                        :isDisabled="!styleOptions.length"
                        :options="styleOptions"
                        validationRules="style-required"
                        placeHolderText="Select style"
                        inputId="styleQuestionField" />
                    <vehicleBanner
                        cmsWidgetName="VehicleBannerWidget"
                        :displayGenericVehicleImage="displayGeneric"
                        :displayVehicleImage="imageUrl"
                        :vehicleCategory="category"
                        :displayUnmatchedVehicleIcon="unmatchedVehicleIcon"
                        class="mt-5 vehicle-footer"
                        ref="banner" />

                    <navbar
                        cmsWidgetName="FunnelFooterWidget"
                        @ForwardClicked="forwardButtonAction"
                        :isForwardActionDisabled="!meta.valid"
                        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 vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
import vehicleQuestion from "@/layouts/vehicle/vehicle-question/vehicle-question";

// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { experimentUniverses } from "@/constants/experiments";
import { getDeviceIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import { Form, defineRule } from "vee-validate";
import { required } 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";

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

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

    async beforeRouteEnter(to, from, next) {
        // Call APIs

        const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
        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;

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

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

            styleQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging(
                storeActions.GET_VEHICLE_STYLES,
                {
                    year: store.getters.order.vehicle.year,
                    make: store.getters.order.vehicle.make,
                    model: store.getters.order.vehicle.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,
                {
                    userId: getDeviceIdValue(),
                    sessionKey: getSessionKeyValue(),
                    pageName: to.query.fmgPage,
                    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);

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

            if (
                makeQuestionInitialDataPromise &&
                modelQuestionInitialDataPromise &&
                styleQuestionInitialDataPromise
            )
                vm.initializeMMSComponent(
                    resultMap.makeQuestionInitialData,
                    resultMap.modelQuestionInitialData,
                    resultMap.styleQuestionInitialData
                );
        });
    },

    watch: {
        async selectedYear(year) {
            if (year) {
                const result = await this.getMakeOptions(year);
                this.makeOptions = result?.data;
                if (this.selectedYearfromStore() !== year) {
                    this.selectedMake = null;
                    this.selectedModel = null;
                    this.selectedStyle = null;
                }
            } else {
                this.makeOptions = [];
                this.selectedMake = null;
                this.selectedModel = null;
                this.selectedStyle = null;
            }
        },
        async selectedMake(make) {
            if (make) {
                const result = await this.getModelOptions(this.selectedYear, make);
                this.modelOptions = result?.data;
                if (this.modelOptions.length === 1) this.selectedModel = this.modelOptions[0];
                else {
                    this.selectedModel = null;
                    this.selectedStyle = null;
                }
            } else {
                this.modelOptions = [];
                this.selectedModel = null;
                this.selectedStyle = null;
            }
        },
        async selectedModel(model) {
            if (model) {
                const result = await this.getStyleOptions(
                    this.selectedYear,
                    this.selectedMake,
                    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;
            } else {
                this.styleOptions = [];
                this.selectedStyle = null;
            }
        },
        async selectedStyle(style) {
            if (style) {
                this.getVehicleDetails();
            } else {
                this.imageUrl = null;
            }
        },
    },
    computed: {
        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;
        },
    },
    methods: {
        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;
        },

        async forwardButtonAction() {
            this.dispatchStoreAction(
                storeActions.SAVE_VEHICLE,
                {
                    year: this.selectedYear,
                    make: this.selectedMake,
                    model: this.selectedModel,
                    style: this.selectedStyle,
                    carId: this.carId,
                    category: this.category,
                    imageUrl: this.imageUrl,
                    imageVifNumber: this.imageVifNumber,
                    imageVifColor: this.imageVifColor,
                },
                false
            );
            this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
        },
        initializeYearComponent(initialData) {
            this.yearOptions = initialData;
        },
        initializeMMSComponent(makeOptions, modelOptions, styleOptions) {
            this.makeOptions = makeOptions;
            this.modelOptions = modelOptions;
            this.styleOptions = styleOptions;
        },
        selectedYearfromStore() {
            return store.getters.vehicle.year?.toString();
        },
        selectedMakefromStore() {
            return store.getters.vehicle.make;
        },
        selectedModelfromStore() {
            return store.getters.vehicle.model;
        },
        selectedStylefromStore() {
            return store.getters.vehicle.style;
        },
        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;
        },
    },

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

<style lang="scss">
.vehicle-footer {
    margin-bottom: 0;
}
.siteSubHeader {
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
}
</style>
