<!-- Documented in confluence https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Component -->
<template>
    <div
        :class="
            isOverflowScrollable
                ? 'button-question button-question-overflow'
                : 'button-question'
        ">
        <div
            v-if="questionText && answers && answers.length > 0"
            class="question-text d-flex"
            :class="{
                'small-question-text': isSmallQuestionText,
                'small-question-label-text': isSmallQuestionLabelText,
            }">
            <span
                class="w-100"
                :class="questionTextClasses">{{ questionText }}</span>
        </div>
        <div class="w-100 d-flex justify-content-center">
            <fieldset
                class="w-100"
                :aria-required="isRequired"
                :role="isMultiSelect ? 'group' : 'radiogroup'"
                :aria-labelledby="formatString(groupName)">
                <legend
                    :id="formatString(groupName)"
                    class="sr-only"
                    :data-focus-target="formatString(groupName)"
                    tabindex="-1">
                    {{ questionText }}
                    {{
                        isMultiSelect && answers && answers.length > 1
                            ? 'Select one or more options below.'
                            : 'Select an option below.'
                    }}
                </legend>
                <div :class="getComponentLoopWrapperClasses">
                    <div
                        v-for="answer in buttonsInfo"
                        :key="answer.value ?? answer"
                        :class="getComponentWrapperClasses">
                        <component
                            :is="buttonTypeString"
                            v-model="selectedValues"
                            :buttonLabel="answer.buttonLabel"
                            :buttonLabelSubCopy="answer.buttonLabelSubCopy"
                            :buttonBodyCopy="answer.buttonBodyCopy"
                            :buttonAuxiliaryCopy="answer.buttonAuxiliaryCopy"
                            :buttonFooterCopy="answer.buttonFooterCopy"
                            :buttonImage="answer.buttonImage"
                            :buttonImageId="answer.buttonImageId"
                            :groupName="answer.groupName"
                            :isMultiSelect="isMultiSelect"
                            :value="answer.value"
                            :selectingInitiatesLoad="selectingInitiatesLoad"
                            :isWide="isWide"
                            :validationRules="validationRules"
                            :textPosition="textPosition"
                            :additionalButtonData="additionalButtonData"
                            :additionalButtonStyling="additionalButtonStyling"
                            :lastValuePushedToGa="lastValuePushedToGa"
                            :setLastValuePushedToGa="setLastValuePushedToGa"
                            :suppressError="suppressError" />
                        <!-- For nested questions -->
                        <transition
                            name="fade"
                            mode="out-in">
                            <div
                                v-if="
                                    typeof selectedValues == 'string' &&
                                    selectedValues == answer.value
                                ">
                                <slot></slot>
                            </div>
                        </transition>
                    </div>
                </div>
            </fieldset>
        </div>
        <div
            v-if="!suppressError"
            class="row form-test-error mt-1">
            <error-message :name="formatString(groupName)"></error-message>
        </div>
    </div>
</template>

<script>
import listButton from '@/ux-components/list-button/list-button.vue';
import listButtonHorizontal from '@/ux-components/list-button-horizontal/list-button-horizontal.vue';
import listCard from '@/ux-components/list-card/list-card.vue';
import radio from '@/ux-components/radio/radio.vue';
import { useField, ErrorMessage } from 'vee-validate';
import providerPrefRadio from '@/layouts/provider-preference/provider-pref-radio/provider-pref-radio.vue';

export default {
    name: 'button-question',
    components: {
        listButton,
        listButtonHorizontal,
        listCard,
        ErrorMessage,
        radio,
        providerPrefRadio
    },
    props: {
        buttonTypeString: {
            type: String,
            default: 'listButton'
        },
        buttonTypeObject: {
            type: Object,
            default: null
        },
        isMultiSelect: Boolean,
        groupName: String,
        questionText: String,
        answers: Array,
        questionTextClasses: Array,
        textPosition: {
            type: String,
            default: 'text-center'
        },
        selectingInitiatesLoad: Boolean,
        isRequired: Boolean,
        isOverflowScrollable: Boolean,
        isWide: Boolean,
        isCashOrInsurance: Boolean,
        modelValue: [Array, Number, String],
        value: [Number, String],
        validationRules: String,
        suppressError: Boolean,
        useTextForValue: Boolean,
        valueToLogType: String,
        additionalButtonData: Object,
        additionalButtonStyling: String,
        isSmallQuestionText: Boolean,
        isSmallQuestionLabelText: Boolean
    },
    emits: ['update:modelValue'],
    setup(props) {
        const propsClone = { ...props };
        const { modelValue } = propsClone;

        const fieldOptions = {
            value: modelValue,
            initialValue: null
        };

        const {
            errorMessage,
            handleBlur,
            handleChange,
            meta,
            validate,
            errors,
            resetField
        } = useField(props.groupName, props.validationRules, fieldOptions);

        return {
            errorMessage,
            handleBlur,
            handleChange,
            validate,
            meta,
            errors,
            resetField
        };
    },
    data() {
        return {
            lastValuePushedToGa: null
        };
    },
    computed: {
        getFieldSetClasses() {
            // eslint-disable-next-line no-nested-ternary
            const baseClasses = this.isOverflowScrollable
                ? 'container-fluid overflow-scroll position-absolute px-5 pt-1 py-0'
                : this.buttonTypeString === 'listCard'
                    ? 'w-100'
                    : '';

            const SmallQuestionTextClass = this.isSmallQuestionText
                ? `${baseClasses}small-question-text`
                : baseClasses;

            const SmallQuestionLabelText = this.isSmallQuestionLabelText
                ? `${SmallQuestionTextClass}small-question-label-text`
                : SmallQuestionTextClass;
            return SmallQuestionLabelText;
        },
        getComponentLoopWrapperClasses() {
            let classes;
            switch (this.buttonTypeString) {
                case 'listButton':
                    classes = 'w-100';
                    break;
                case 'listButtonHorizontal':
                    classes = 'd-flex flex-row p-0';
                    break;
                case 'listCard':
                    classes =
                        'row g-2 g-md-5 justify-content-center mb-1 flex-nowrap';
                    if (this.isWide) {
                        classes += ' flex-column';
                    }
                    break;
                case 'radio':
                    classes = 'ui-radio d-flex';
                    break;
                case 'servicePackageRadio':
                    classes = 'package-main';
                    break;
                case 'providerPrefRadio':
                    classes = 'option-main';
                    break;
                default:
            }
            return classes;
        },
        getComponentWrapperClasses() {
            let classes = '';

            classes += this.isWide ? 'col-12' : 'col';

            switch (this.buttonTypeString) {
                case 'radio':
                    classes += ' radio-button-container';
                    break;
                case 'servicePackageRadio':
                    classes = 'package-wrapper';
                    break;
                case 'providerPrefRadio':
                    classes = 'option-wrapper';
                    break;
                default:
            }
            // Determine number of buttons and add class accordingly.
            // This is to accommodate unique spacing per design specs.
            if (
                this.buttonTypeString === 'listCard'
                && this.buttonsInfo.length > 2
            ) {
                classes += ' two-list-card-width';
            }

            if (
                this.buttonTypeString === 'listCard'
                && this.buttonsInfo.length === 1
            ) {
                classes += ' one-list-card-width';
            }

            return classes;
        },
        buttonsInfo() {
            return (Array.isArray(this.answers) ? this.answers : [])?.map((answer) => ({
                buttonLabel: answer.buttonLabel ?? answer.Text ?? answer,
                altText:
                        answer.altText ?? (answer.Name ? answer.Name : answer),
                buttonLabelSubCopy:
                        answer.buttonLabelSubCopy ?? answer.SubText,
                buttonBodyCopy:
                        answer.buttonBodyCopy ?? answer.buttonBodyCopy,
                buttonAuxiliaryCopy:
                        answer.buttonAuxiliaryCopy
                        ?? answer.buttonAuxiliaryCopy,
                buttonFooterCopy:
                        answer.buttonFooterCopy ?? answer.buttonFooterCopy,
                buttonImage: answer.buttonImage ?? answer.AnswerImageUrl,
                buttonImageId: answer.buttonImageId ?? answer.ImageId,
                groupName: this.formatString(this.groupName),
                value:
                        answer.value
                        ?? (this.useTextForValue && answer.Text
                            ? answer.Text
                            : answer.Name)
                        ?? (typeof answer !== 'object' ? answer : null)
            }));
        },
        selectedValues: {
            get() {
                return this.modelValue;
            },
            set(selectedAnswers) {
                this.$emit('update:modelValue', selectedAnswers);
            }
        }
    },
    watch: {
        modelValue(newValue) {
            this.resetField({
                value: newValue
            });
        }
    },
    beforeMount() {
        if (this.buttonTypeObject) {
            this.$options.components[this.buttonTypeString] =
                this.buttonTypeObject;
        }
    },
    beforeUnmount() {
        this.resetField({
            value: ''
        });
    },
    methods: {
        formatString(str) {
            return String(str).replaceAll(' ', '-');
        },
        setLastValuePushedToGa(lastValuePushedToGa) {
            this.lastValuePushedToGa = lastValuePushedToGa;
        }
    }
};
</script>

<style lang="scss" scoped>
.button-question {
    color: $black;

    .radio-button-container {
        &:not(:last-child) {
            padding-bottom: map-get($spacers, 2);
        }
    }

    .question-text {
        margin-bottom: .625rem;
        font-size: 1rem;
        line-height: 1.625rem;

        span {
            &.select-all-glass-parts {
                color: #525656;
            }
            &.button-question-text-left {
                text-align: left;
            }
        }
    }

    &.provider-preference {
        .question-text {
            span {
                text-align: left;
            }
        }
    }
}

.small-question-text {
    &.question-text {
        span {
            font-size: 0.875rem;
            text-align: left;
            margin: 0 0 0.5rem 0;
        }
    }
    &.question-text {
        margin: 0;
    }
    &fieldset {
        .ui-radio {
            margin: 0;
        }
    }
}

.small-question-label-text {
    &.question-text {
        span {
            text-align: left;
            margin: 0 0 0.25rem 0;
        }
    }
    &.question-text {
        margin: 0;
    }
    &fieldset {
        .ui-radio {
            margin: 0;
        }
    }
}
</style>
