<template>
    <Form
        ref="theForm"
        @submit="onSubmit"
        @invalidSubmit="onInvalidSubmit">
        <div class="fade-on-route-transition">
            <div class="justify-content-center">
                <siteHeader cmsWidgetName="SiteHeaderWidget" />
            </div>
            <div class="iss-heritage-container-width">
                <div class="vehicle-parts-container iss-heritage-content-container-width">
                    <siteSubHeader
                        ref="siteSubHeader"
                        class="mt-4"
                        cmsWidgetName="SiteSubHeaderWidget" />
                    <alert
                        id="vehicle-parts-alert"
                        class="mt-3 mb-3"
                        alertClass="alert-warning"
                        cmsWidgetName="AlertWidget"
                        :isDismissible="false" />
                    <div
                        v-for="(item, i) in PartsOrQuestions"
                        :key="i">
                        <!-- Render horizontal lines if there is multi-glass (aka if i > 0) -->
                        <hr v-if="i > 0" />
                        <glassPartQuestion
                            :ref="`${RefPrefix}-${item.glassLocation}-${item.glassName}`"
                            v-model="selectedGlassParts[item.glassLocation + '-' + item.glassName]"
                            :glassLocation="item.glassLocation"
                            :glassName="item.glassName"
                            :colorAnswers="item.colorAnswers"
                            :alreadyPopulatedPartsData="alreadyPopulatedPartsData" />
                    </div>
                    <siteFooter
                        ref="siteFooter"
                        class="mt-5"
                        cmsWidgetName="SiteFooterWidget"
                        :isForwardActionDisabled="isForwardActionDisabled"
                        @backClicked="navigateBackByVehicleQuestions"
                        @ForwardClicked="forwardButtonAction" />
                </div>
            </div>
        </div>
    </Form>
</template>

<script>
// Components
import glassPartQuestion from '@/layouts/vehicle-parts/glass-part-question/glass-part-question.vue';
import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import alert from '@/ux-components/alert/alert.vue';

// Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper';
import issPageValues from '@/router/router-constants/issPage-values';
import { Form } from 'vee-validate';
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';

export default {
    name: 'vehicle-parts',
    components: {
        // eslint-disable-next-line vue/no-reserved-component-names
        Form,
        glassPartQuestion,
        siteHeader,
        siteSubHeader,
        siteFooter,
        alert
    },
    mixins: [BaseFormMixin, vehicleQuestionsMixin],
    async beforeRouteEnter(to, from, next) {
        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
        // Settle promises and get results
        const promiseResultMap = [
            {
                resultKey: 'cmsContent',
                promise: cmsContentPromise
            }
        ];
        const resultMap = await settleAllPromises(promiseResultMap);
        // Call the "next" function to complete the transition to this page.
        next((vm) => {
            vm.setCmsContent(resultMap.cmsContent);

            // Glass Part Question dynamic component
            Object.keys(vm.$refs)
                .filter((r) => r.includes(vm.RefPrefix) && vm.$refs[r][0] !== undefined)
                .forEach((c) =>
                    vm.$refs[c][0].initializeComponent({
                        ColorQuestionWidget:
                            resultMap.cmsContent.ColorQuestionWidget,
                        FeatureQuestionWidget:
                            resultMap.cmsContent.FeatureQuestionWidget
                    }));
        });
    },
    data() {
        return {
            selectedGlassParts: {},
            alertWidgetData: Object,
            alreadyPopulatedPartsData: []
        };
    },
    computed: {
        isForwardActionDisabled() {
            return this.selectedGlassPartNumbers?.length !== this.PartsFromApi.partsOrQuestions?.length;
        },
        selectedGlassPartNumbers() {
            // Compile all selected parts from the page.
            const numberArray = [];
            // eslint-disable-next-line no-restricted-syntax
            for (const glassPart of Object.values(this.selectedGlassParts)) {
                if (glassPart?.partNumber) {
                    numberArray.push(glassPart.partNumber);
                }
            }
            return numberArray;
        },
        PartsOrQuestions() {
            const partsData = this.PartsFromApi;

            // Map API result data, to vehicle-parts data structure
            const mappedData = partsData.partsOrQuestions?.map((g) => ({
                glassName: g.glassName,
                glassLocation: g.glassLocation,
                colorAnswers: g.parts?.reduce((arr, p) => {
                    arr.push({
                        ColorAnswerText: p.color,
                        FeatureAnswers: [
                            {
                                FeatureAnswerText:
                                    p.description === ''
                                        ? p.color
                                        : p.description,
                                PartNumber: p.partNumber
                            }
                        ]
                    });
                    return arr;
                }, [])
            }));

            return mappedData;
        },

        PartsFromApi() {
            return this.mainStore.pageData(issPageValues.VEHICLE_PARTS);
        },

        RefPrefix() {
            return 'partQuestion';
        }
    },
    mounted() {
        this.LoadInitialPartsData();
    },
    methods: {
        arePagePrerequisitesValid() {
            // Check if isRepair is populated and if the pageData we need is here (Parts data)
            return (
                useMainStore().damage.isRepair != null
                && useMainStore().pageData(issPageValues.VEHICLE_PARTS)
                && Object.keys(useMainStore().pageData(issPageValues.VEHICLE_PARTS)).length !== 0
            );
        },
        async forwardButtonAction() {
            const matchedParts = [];

            // Match them to the parts from the API.
            // eslint-disable-next-line no-restricted-syntax
            for (const [key, value] of Object.entries(this.PartsFromApi.partsOrQuestions)) {
                // eslint-disable-next-line no-restricted-syntax
                for (const [partKey, partValue] of Object.entries(value.parts)) {
                    const currentPart =
                        this.PartsFromApi.partsOrQuestions[key].parts[partKey];

                    const isMatched = this.selectedGlassPartNumbers.some((p) => p === currentPart.partNumber);

                    if (isMatched) {
                        matchedParts.push({
                            glassLocation: value.glassLocation,
                            glassName: value.glassName,
                            parts: [currentPart]
                        });
                    }
                }
            }
            // If no parts could be matched, throw an error (isForwardActionDisabled is based off of matchedParts)
            if (this.isForwardActionDisabled) {
                throw new Error('Could not match any parts to the selected parts');
            }

            this.navigateForward(matchedParts, null);
        },

        LoadInitialPartsData() {
            const partsData = this.PartsFromApi;
            this.alreadyPopulatedPartsData =
                this.mainStore.lineItems.glassParts === null
                    ? []
                    : this.mainStore.lineItems.glassParts;

            partsData.partsOrQuestions.map((g) => {
                // If the part is already populated, use the value from the store and populate the v-model.
                Object.keys(this.alreadyPopulatedPartsData).forEach((key) => {
                    const { partNumber } = this.alreadyPopulatedPartsData[key];
                    g.parts.forEach((p) => {
                        if (p.partNumber === partNumber) {
                            this.selectedGlassParts[
                                `${g.glassLocation}-${g.glassName}`
                            ] = p;
                        }
                    });
                });
            });
        }
    }
};
</script>
<style lang="scss" scoped>
.iss-heritage-container-width {
    .vehicle-parts-container {
        position: relative;
        min-height: 1px;
        padding-left: .9375rem;
        padding-right: .9375rem;

        #vehicle-parts-alert {
            .alert-heading {
                margin-top: 0.25rem !important;
            }
        }
    }
}
</style>
