<template>
    <div class="row">
        <p class="mb-0 color-question-text">
        {{ colorQuestionText }}
        </p>
    </div>
    <div class="nested-radio">
        <div class="row my-2">
            <div class="col">
                <buttonQuestion
                    v-model="selectedTint"
                    :answers="tintSelectionOptions"
                    buttonTypeString="listCard"
                    :isWide="true"
                    altText=""
                    isRequired
                    :groupName="replaceAllSpaceWithDash(`${glassLocation}-${glassName}`)"
                    :validationRules="tintValidationRules">
                    <div
                        class="row my-2"
                        aria-live="polite">
                        <div class="col">
                            <buttonQuestion
                                id="glass-part-question"
                                v-model="selectedPartNumber"
                                buttonTypeString="radio"
                                class="radioQuestion"
                                :questionText="glassFeatureQuestion"
                                :answers="featureListData[selectedTint]"
                                textPosition="text-start"
                                :loaderEnabled="false"
                                isRequired
                                isSmallQuestionText
                                :groupName="replaceAllSpaceWithDash(`${glassLocation}-${glassName}-${selectedTint}`)"
                                :validationRules="partValidationRules" />
                        </div>
                    </div>
                </buttonQuestion>
            </div>
        </div>
    </div>
</template>

<script>
// Components
import buttonQuestion from '@/digital-components/button-question/button-question.vue';

// Supporting files
import getTintImage from '@/constants/tint-mapper';
import getCustomTransformValue from '@/constants/dynamictext-mapper';
import { defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages';
import { useMainStore } from '@/store';

export default {
    name: 'glass-part-question',
    components: {
        buttonQuestion
    },
    inheritAttrs: false,
    props: {
        glassName: String,
        glassLocation: String,
        colorAnswers: Array,
        modelValue: Object,
        alreadyPopulatedPartsData: {
            type: Array,
            default: () => []
        }
    },
    emits: ['update:modelValue'],
    data() {
        return {
            glassColorQuestion: '',
            glassFeatureQuestion: '',
            selectedTint: ''
        };
    },
    computed: {
        tintValidationRules() {
            const validationRuleName = `${this.glassLocation}-${this.glassName}-tint-required`;

            defineRule(validationRuleName, required(errorMessages.OPTION_REQUIRED));

            return validationRuleName;
        },
        partValidationRules() {
            const validationRuleName = `${this.glassLocation}-${this.glassName}-part-required`;

            defineRule(validationRuleName, required(errorMessages.OPTION_REQUIRED));
            return validationRuleName;
        },
        colorQuestionText() {
            return getCustomTransformValue(
                this.glassColorQuestion,
                `${this.glassLocation} ${this.glassName}`
            );
        },

        tintSelectionOptions() {
            const tintOptions = [];

            Object.keys(this.featureListData).forEach((tintOption) => {
                const buttonImage = this.getTintSourceImage(this.glassLocation, tintOption);
                tintOptions.push({
                    value: tintOption,
                    buttonLabel: tintOption,
                    buttonImage: buttonImage ? require(`@/assets/img/tints/${buttonImage}`) : null
                });
            });

            return tintOptions;
        },

        selectedPartNumber: {
            get() {
                return this.modelValue?.partNumber;
            },
            set(newValue) {
                const part = this.partsForSelectedTint
                    .filter((partItem) => partItem.partNumber === newValue?.value)[0];
                this.$emit('update:modelValue', part);
            }
        },

        partsForSelectedTint() {
            const matchingGlass = this.PartDataFromApi.partsOrQuestions?.filter((dataForGlassLocationAndName) =>
                dataForGlassLocationAndName.glassName === this.glassName
                    && dataForGlassLocationAndName.glassLocation === this.glassLocation);
            const matchingGlassParts = matchingGlass?.length === 1 ? matchingGlass[0].parts : [];
            return matchingGlassParts.filter((part) => part.color === this.selectedTint) ?? [];
        },

        // Creates a map of the feature list data in the correct Name/Value
        // format for the button-question component.
        featureListData() {
            const tintMapByColor = this.colorAnswers.reduce((arr, item) => {
                // Create the key
                const itemColor = item.ColorAnswerText;
                arr[itemColor] = arr[itemColor] || [];

                // Map the data to Name/Text object for ButtonQuestion
                const mappedItem = item.FeatureAnswers.reduce((featureArr, it) => {
                    featureArr.Text = it.FeatureAnswerText; // Display to User
                    featureArr.Name = it.PartNumber; // Backing Value

                    return featureArr;
                }, {});

                // Add onto the final object
                arr[itemColor].push(mappedItem);
                return arr;
            }, {});

            return tintMapByColor;
        },

        PartDataFromApi() {
            return this.mainStore.pageData(this.$route.query.issPage) ?? {};
        }
    },
    watch: {
        selectedTint() {
            this.AutoSelectIfSinglePart();
        }
    },
    mounted() {
        this.LoadPreselectedValues();
    },
    methods: {
        // Initialize the component data
        initializeComponent(cmsContent) {
            this.glassColorQuestion = cmsContent.ColorQuestionWidget.QuestionText;
            this.glassFeatureQuestion = cmsContent.FeatureQuestionWidget.QuestionText;
        },

        // Gets tint images based on the glass type, and tint name.
        // Returns an empty string if the src or object is undefined.
        getTintSourceImage(glassLocation, tintColor) {
            const tintSourceObject = getTintImage(glassLocation, tintColor);

            if (tintSourceObject === undefined || !tintSourceObject.src) {
                return '';
            }

            return tintSourceObject.src;
        },

        AutoSelectIfSinglePart() {
            if (this.partsForSelectedTint?.length > 0) {
                // Check if only a single part is present for the tint and set the v-model if it is.
                if (this.partsForSelectedTint?.length === 1) {
                    // select element with matching partNumber
                    this.updateSelectedPartNumber(this.partsForSelectedTint[0].partNumber);
                } else {
                    this.selectedPartNumber = null;
                }
            }
        },

        // Loads the preselected values from the store.
        LoadPreselectedValues() {
            this.$nextTick(() => {
                // Populate button-question model-value if parts data already exists in store
                if (this.modelValue !== undefined) {
                    this.selectedTint = this.modelValue.color;
                    const { glassParts } = useMainStore().order.lineItems;
                    if (glassParts) {
                        for (const tintPart of this.partsForSelectedTint) {
                            for (const glassPart of glassParts) {
                                if (tintPart.partNumber === glassPart.partNumber) {
                                    this.$nextTick(() => {
                                        this.updateSelectedPartNumber(tintPart.partNumber);
                                    });
                                    return;
                                }
                            }
                        }
                    }
                }
            });
        },

        updateSelectedPartNumber(partNumber) {
            this.selectedPartNumber = { value: partNumber };
            this.$nextTick(() => {
                const radioInput = document.querySelector(`input[value=${this.selectedPartNumber}]`);
                // Fire a click event on the input so the field is updated
                radioInput?.click();
            });
        },

        replaceAllSpaceWithDash(str) {
            return String(str).replaceAll(' ', '-');
        }
    }
};
</script>

<style lang="scss" scoped>
.nested-radio {
    :deep(.ui-radio) {
        flex-direction: column;
        margin: 0.25rem 0;
    }

    p {
        font-size: 0.875rem;
    }
}

.color-question-text {
    color: $black;
    font-weight: $font-weight-bold;
}

#glass-part-question {
    span.fw-bold.w-100 {
        margin-top: 0.5rem;
        margin-bottom: 0;
    }
    div.col.radio-button-container {
        padding-bottom: 0;
    }
}
</style>
