<template>
    <div class="flex-column-20">
        <BsMultiSelect
            v-for="(layer, index) in possibleOptions.slice(1)"
            v-if="transformedTree"
            v-show="!isEmpty(layer)"
            :model-value="selectedOptions![index+1]"
            @update:model-value="updateSelectedOptions(index + 1, $event)"
            :label="`Select ${layerNames[index + 1]}`"
            :all-options="layer"
        ></BsMultiSelect>
    </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

import { FrontendParameters } from "./model";
import { DFCParamsBranch } from "./demandForecastParametersTree";
import { isEmpty, isEqual } from "lodash";
import { PropType } from "vue";
import { useLocalStorage } from "./composables/use-local-storage";
import BsMultiSelect from "./BsMultiSelect.vue";
import useProductStore from "../store/ProductStore";

export default defineComponent({
    name: "DemandForecastParameters",
    components: {
        BsMultiSelect,
    },
    setup(props, ctx) {
        const { data: selectedOptions } = useLocalStorage<string[][]>(
            `${ useProductStore().webAppId}.selectedOptions.` + props.tag
        );
        return { selectedOptions };
    },
    emits: ["update:selected-granularities", "update:selected-products"],
    props: {
        tag: {
            // History tag to differenciate selections in diff components
            type: String,
            default: "",
        },
        frontendParameters: {
            required: true,
            type: Object as PropType<FrontendParameters>,
        },
    },
    data() {
        return {
            possibleOptions: undefined as unknown as string[][],
            transformedTree: undefined as unknown as DFCParamsBranch,
            layerNames: undefined as unknown as string[],
            lastEmittedValue: {
                granularities: [] as string[],
                products: [] as string[],
            },
            isEmpty,
            productIdHelpMessage: "Select a product to customize",
        };
    },
    methods: {
        init() {
            this.transformFrontendParams(this.frontendParameters);
            this.initLocalVariables();
        },
        initLocalVariables() {
            this.layerNames = [
                "granularity",
                ...this.frontendParameters.hierarchy_data.product_hierarchy,
            ];
            if (this.selectedOptions == null) {
                this.selectedOptions = new Array(this.layerNames.length)
                    .fill(undefined)
                    .map((_) => []);
            }
            this.updateSelectModel(this.selectedOptions);
            // Removing granularity from user selection
            this.updateSelectedOptions(0, this.possibleOptions[0]);
        },
        transformFrontendParams(frontendParameters: FrontendParameters) {
            DFCParamsBranch.setFrontendParams(frontendParameters);
            this.transformedTree = new DFCParamsBranch();
        },
        updateSelectModel(selectedOptions?: string[][]) {
            if (selectedOptions) this.selectedOptions = selectedOptions;
            if (this.selectedOptions != null) {
                this.possibleOptions = this.transformedTree.getAdjacentBranches(
                    this.selectedOptions
                );
                if (this.possibleOptions != null) {
                    this.selectedOptions = this.selectedOptions.map(
                        (layerSelectedOptions, index) => {
                            return layerSelectedOptions.filter(
                                (selectedOption) =>
                                    // @ts-ignore
                                    this.possibleOptions[index].includes(
                                        selectedOption
                                    )
                            );
                        }
                    );
                }
            }

            this.emitUpdatedData();
        },
        updateSelectedOptions(layerIndex: number, newVal: string[]) {
            if (this.selectedOptions != null)
                this.selectedOptions[layerIndex] = newVal;
            this.updateSelectModel();
        },
        emitUpdatedData() {
            if (this.selectedOptions != null) {
                const selectedGranularities = this.selectedOptions[0];
                const selectedProducts =
                    this.selectedOptions[this.selectedOptions.length - 1];
                if (
                    !isEqual(
                        selectedGranularities,
                        this.lastEmittedValue.granularities
                    )
                ) {
                    this.$emit("update:selected-granularities", [
                        ...selectedGranularities,
                    ]);
                    this.lastEmittedValue.granularities = [
                        ...selectedGranularities,
                    ];
                }
                if (
                    !isEqual(selectedProducts, this.lastEmittedValue.products)
                ) {
                    this.$emit("update:selected-products", [
                        ...selectedProducts,
                    ]);
                    this.lastEmittedValue.products = [...selectedProducts];
                }
            }
        },
        layerHelpMessage(index: number) {
            if (
                this.possibleOptions != null &&
                index === this.possibleOptions.length - 1
            ) {
                return this.productIdHelpMessage;
            }
        },
    },
    mounted() {
        this.init();
    },
});
</script>

<style scoped lang="scss">
.appearing-clearable-field {
    display: none;
    &.appearing-clearable-field--active {
        display: block;
    }
}
</style>
