<template>
    <DropdownList
        v-if="view === ''"
        :search.sync="search"
        :entries="sourcesList"
        @resolve="({ value }) => setQuery({ name: value })"
    >
        <template #nav>
            <a class="uk-margin-left" @click.prevent="$emit('config')">
                <span uk-icon="more-vertical" class="uk-icon-link"></span>
            </a>
        </template>
    </DropdownList>

    <DropdownList
        v-else
        :search.sync="search"
        :entries="fieldsList"
        :selected="selectedField"
        @resolve="({ value }) => setField(value)"
    >
        <template #nav>
            <div class="uk-flex uk-flex-right uk-flex-middle">
                <span v-if="selectedField" class="uk-text-meta uk-disabled">{{
                    selectedLabel
                }}</span>
                <a v-if="selectedField" class="uk-margin-left" @click.prevent="openpanel">
                    <span uk-icon="cog" class="uk-icon-link"></span>
                </a>
                <a v-else class="uk-margin-left" @click.prevent="$emit('config')">
                    <span uk-icon="more-vertical" class="uk-icon-link"></span>
                </a>
            </div>
        </template>
    </DropdownList>
</template>

<script>
import api from '@yootheme/api';
import { includes } from 'uikit-util';
import { DropdownList } from '../../components';

export default {
    name: 'DynamicCustomQuery',

    components: {
        DropdownList,
    },

    inject: ['Builder', '$node', '$prop'],

    data: () => ({
        search: '',
        view: '', // fields|query
        query: {},
    }),

    computed: {
        queryField() {
            const { Schema } = api.builder.helpers;
            return Schema.findField(this.query?.name);
        },

        queryFieldField() {
            const { Schema } = api.builder.helpers;
            return Schema.findField(`${this.query?.name}.${this.query?.field?.name}`);
        },

        selectedLabel() {
            if (!this.queryField) {
                return this.$t('Custom');
            }

            return (
                this.queryField.metadata.label +
                (this.queryFieldField ? ` - ${this.queryFieldField.metadata.label}` : '')
            );
        },

        fieldsList() {
            let fields;
            const { Schema } = api.builder.helpers;

            if (this.query?.field?.name && this.queryFieldField) {
                fields = Schema.getFields(this.queryFieldField);
            } else if (this.query?.name && this.queryField) {
                fields = Schema.getFields(this.queryField);
            }

            return fields.filter(
                (item) =>
                    !this.search || includes(item.text.toLowerCase(), this.search.toLowerCase())
            );
        },

        sourcesList() {
            const Schema = api.builder.helpers.Schema;

            function filterByView(views, view) {
                return !views || includes(views, view);
            }

            const labels = {
                Page: this.$t('Page'),
                Parent: this.$t('Parent'),
                Global: this.$t('Global'),
                Submission: this.$t('Submission'),
            };

            const fields = Schema.rootQueryFields
                ?.filter((field) => filterByView(field.metadata?.view, this.Builder?.view))
                ?.filter((field) => field.metadata?.group)
                ?.filter((field) => field.metadata?.group !== labels.Parent)
                ?.filter((field) => field.metadata?.group !== labels.Page)
                ?.filter((field) => field.metadata?.group !== labels.Global)
                ?.filter((field) => field.metadata?.group !== labels.Submission)
                .map(({ name, metadata: { label, group } = {} }) => ({
                    value: name,
                    text: label || name,
                    group,
                }));

            return fields.filter(
                (item) =>
                    !this.search || includes(item.text.toLowerCase(), this.search.toLowerCase())
            );
        },

        selectedField() {
            return this.$prop?.name;
        },
    },

    created() {
        if (this.$prop?.query?.name) {
            this.setQuery(this.$prop.query);
        }
    },

    methods: {
        setQuery(query) {
            this.query = query;
            this.view = 'fields';
            this.search = '';
        },

        setField(name) {
            if (!this.selectedField) {
                this.openpanel();
            }

            this.$emit('resolve', { name, query: this.query, enforce: true });
        },

        openpanel() {
            this.$trigger('openAdjacentPanel', {
                name: 'custom-query-panel',
                adjacentOf: this.$node,
                fields: {
                    _sourceArgs: {
                        type: 'source-query-args',
                    },
                    _sourceField: {
                        label: 'Multiple Items Source',
                        type: 'source-field-select',
                        description:
                            'Optionally select a related source which has multiple items to map its fields.',
                        show: 'api.builder.helpers.Source.getSourceFieldOptions(this.node)',
                    },
                    _sourceFieldArgs: {
                        type: 'source-field-args',
                    },
                    _sourceFieldDirectives: {
                        type: 'source-field-directives',
                    },
                },
                props: {
                    node: {
                        source: {
                            query: this.query,
                        },
                    },
                    builder: this.Builder,
                    values: {},
                },
            });
        },
    },
};
</script>
