<template>
    <DynamicDropdownOptions
        v-if="!selectedOption"
        :options="options"
        :selected="selectedOption"
        @select="setOption"
    />

    <component
        :is="selectedOption.component"
        v-else-if="selectedOption.component"
        :option="selectedOption"
        @resolve="resolve"
        @config="selectedOption = null"
    />

    <SourceFields
        v-else-if="getOptionFields(selectedOption)"
        :fields="getOptionFields(selectedOption)"
        :selection="selectedField"
        @resolve="resolve"
        @config="selectedOption = null"
    />
</template>

<script>
import api from '@yootheme/api';
import essentials from '../../../api';
import SourceFields from './SourceFields.vue';
import DynamicDropdownOptions from './DynamicDropdownOptions.vue';
import { isFunction } from 'uikit-util';

export default {
    name: 'DynamicDropdown',

    components: {
        SourceFields,
        DynamicDropdownOptions,
    },

    provide() {
        return {
            $node: this.node,
            $field: this.field,
            $prop: this.prop,
            Builder: essentials.Builder,
        };
    },

    props: {
        options: {
            type: Array,
            required: true,
        },
        node: {
            type: Object,
            required: true,
        },
        prop: {
            type: Object,
        },
    },

    data: () => ({
        isSelected: false,
        selectedOption: null,
    }),

    computed: {
        matchedOption() {
            return this.options.find((opt) => opt.match({ node: this.node, prop: this.prop }));
        },

        selectedField() {
            const queryHasChanged = this.selectedOption?.name !== this.matchedOption?.name;

            if (queryHasChanged) {
                return null;
            }

            return this.prop?.name;
        },
    },

    created() {
        if (this.matchedOption) {
            this.selectedOption = this.matchedOption;
        }
    },

    methods: {
        setOption(opt) {
            if (isFunction(opt.onSelection)) {
                opt.onSelection(this);
            }

            this.selectedOption = opt;
        },

        getOptionFields(opt) {
            return (
                opt.fields || api.builder.helpers.Schema.getFields(opt.source({ prop: this.prop }))
            );
        },

        resolve(value) {
            if (!this.selectedOption) {
                return;
            }

            const result = this.selectedOption.resolve({
                ...value,
                prop: this.prop,
            });

            this.$emit('resolve', result);
        },
    },
};
</script>
