<template>
    <div class="windshield-options">
        <windshieldDamageTypeQuestion
            v-model="selectedWindshieldDamageTypeValue"
            cmsWidgetName="WindshieldDamageTypeQuestion"
            :isAvailable="isWindshieldDamageLocation"
            :suppressError="hasRepairReplaceConflict || showNoReplacementAvailableError"
            groupName="WindshieldDamageTypeQuestion"
            :validationRules="windshieldDamageTypeQuestionValidationRules" />
        <alert
            v-if="showNoReplacementAvailableError"
            class="my-3"
            cmsWidgetName="NoReplacementAvailableError"
            alertClass="alert-danger"
            :isDismissible="false" />
        <windshieldChipCountQuestion
            v-model="selectedWindshieldChipCountValues"
            cmsWidgetName="WindshieldChipCountQuestion"
            :isAvailable="isRepairOptionSelected && !hasRepairReplaceConflict"
            groupName="WindshieldChipCountQuestion"
            validationRules="windshield-chip-count-required" />
        <replaceOptionsQuestion
            ref="replaceOptionsQuestion"
            v-model="selectedWindshieldReplaceOptionsValues"
            cmsWidgetName="WindshieldReplaceOptionsQuestion"
            :isAvailable="isReplaceOptionSelected"
            isMultiSelect
            groupName="WindshieldReplaceOptions"
            validationRules="windshield-replace-options-required|prevent-split-and-single-together"
            :suppressError="hasSplitSingleConflict"
            isRequired />
        <alert
            v-if="hasSplitSingleConflict"
            class="mt-5"
            cmsWidgetName="SplitSingleConflict"
            alertClass="alert-danger"
            :isDismissible="false" />
    </div>
</template>

<script>
import windshieldDamageTypeQuestion from
    '@/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question.vue';
import windshieldChipCountQuestion from
    '@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question.vue';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
import alert from '@/ux-components/alert/alert.vue';

import { defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages';
import damageLocationsSelected from '@/constants/damage-locations-selected.js';

// DEFINE VALIDATION RULES
defineRule(
    'windshield-damage-type-required',
    required(errorMessages.WINDSHIELD_DAMAGE_TYPE_REQUIRED)
);
defineRule(
    'windshield-chip-count-required',
    required(errorMessages.WINDSHIELD_CHIP_COUNT_REQUIRED)
);
defineRule(
    'windshield-replace-options-required',
    required(errorMessages.WINDSHIELD_REPLACE_OPTIONS_REQUIRED)
);

defineRule(
    'check-for-repair-and-replace',
    (selectedWindshieldDamageType, selectedDamageLocations) => (
        selectedWindshieldDamageType.toString() !== damageLocationsSelected.REPAIR
            || (!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD)
                && !selectedDamageLocations[0]?.includes(damageLocationsSelected.WINDSHIELD))
            || selectedDamageLocations[0].length === 1
    )
);
defineRule('repair-only', (value) => value.toString() === damageLocationsSelected.REPAIR);
defineRule('prevent-split-and-single-together', (value) => {
    if (
        value.toString().toUpperCase().includes(damageLocationsSelected.SINGLE.toUpperCase())
        && (value.toString().toUpperCase().includes(damageLocationsSelected.DRIVER.toUpperCase())
            || value
                .toString()
                .toUpperCase()
                .includes(damageLocationsSelected.PASSENGER.toUpperCase()))
    ) {
        return false;
    }
    return true;
});

export default {
    name: 'windshield-options',
    components: {
        windshieldDamageTypeQuestion,
        windshieldChipCountQuestion,
        replaceOptionsQuestion,
        alert
    },

    props: {
        modelValue: Object,
        selectedDamageLocations: Array,
        hasRepairReplaceConflict: Boolean,
        hasSplitSingleConflict: Boolean
    },
    emits: ['update:modelValue'],
    data() {
        return {
            windshieldAvailableReplacementOptions: Object
        };
    },
    computed: {
        selectedValues: {
            get() {
                return this.modelValue;
            },
            set(newValue) {
                this.$emit('update:modelValue', newValue);
            }
        },
        selectedWindshieldDamageTypeValue: {
            get() {
                return this.selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD)
                    ? this.selectedValues.selectedWindshieldDamageType
                    : null;
            },
            set(newValue) {
                this.selectedValues = this.getWindshieldOptions(newValue, null, null);
            }
        },
        selectedWindshieldChipCountValues: {
            get() {
                return this.selectedValues.selectedWindshieldChipCount;
            },
            set(newValue) {
                this.selectedValues = this.getWindshieldOptions(
                    this.selectedWindshieldDamageTypeValue,
                    newValue,
                    null
                );
            }
        },
        selectedWindshieldReplaceOptionsValues: {
            get() {
                return this.selectedValues.selectedWindshieldReplaceOptions;
            },
            set(newValue) {
                this.selectedValues = this.getWindshieldOptions(
                    this.selectedWindshieldDamageTypeValue,
                    null,
                    newValue
                );
            }
        },
        isWindshieldDamageLocation() {
            return this.selectedDamageLocations.some((selectedDamageLocation) =>
                selectedDamageLocation === damageLocationsSelected.WINDSHIELD);
        },
        isRepairOptionSelected() {
            if (!this.selectedWindshieldDamageTypeValue) return false;

            return (
                this.selectedWindshieldDamageTypeValue === damageLocationsSelected.REPAIR
                && this.isWindshieldDamageLocation
            );
        },
        isReplaceOptionSelected() {
            if (!this.selectedWindshieldDamageTypeValue) return false;

            return (
                this.selectedWindshieldDamageTypeValue === damageLocationsSelected.REPLACE
                && this.isWindshieldDamageLocation
            );
        },
        isWindshieldReplaceAvailable() {
            return !(
                Array.isArray(this.windshieldAvailableReplacementOptions)
                && this.windshieldAvailableReplacementOptions.length < 1
            );
        },
        isSplitWindshieldOption() {
            const options = this.windshieldAvailableReplacementOptions.toString().toUpperCase();
            if (options.includes('DRIVER') && options.includes('PASSENGER')) {
                return true;
            }
            return false;
        },
        showNoReplacementAvailableError() {
            if (this.isReplaceOptionSelected && !this.isWindshieldReplaceAvailable) {
                return true;
            }
            return false;
        },
        windshieldDamageTypeQuestionValidationRules() {
            // Note: the validation rules string is not dynamic (it cannot be changed once component has been created)
            let validationRules =
                'windshield-damage-type-required|check-for-repair-and-replace:@DamageLocationQuestion';
            // if vehicle has no windshield replacement option
            if (!this.isWindshieldReplaceAvailable) {
                validationRules = validationRules.concat('|repair-only');
            }
            return validationRules;
        }
    },

    methods: {
        initializeComponent(windshieldAvailableReplacementOptions) {
            this.windshieldAvailableReplacementOptions = windshieldAvailableReplacementOptions;
            this.$refs.replaceOptionsQuestion.initializeComponent(windshieldAvailableReplacementOptions);
        },
        getWindshieldOptions(
            selectedWindshieldDamageType,
            selectedWindshieldChipCount,
            selectedWindshieldReplaceOptions
        ) {
            // ONLY UPDATE THE NEW VALUE IF IT IS TRUTHY (NOT NULL)
            return {
                selectedWindshieldDamageType: selectedWindshieldDamageType || this.selectedValues.selectedWindshieldDamageType,
                selectedWindshieldChipCount: selectedWindshieldChipCount || this.selectedValues.selectedWindshieldChipCount,
                selectedWindshieldReplaceOptions: selectedWindshieldReplaceOptions || this.selectedValues.selectedWindshieldReplaceOptions
            };
        }
    }
};
</script>
