<template>
    <div>
        <div class="yo-dropdown-header">
            <div class="uk-flex uk-flex-middle">
                <div
                    class="uk-search uk-search-default uk-flex-1"
                    :class="{ 'uk-margin-right': $slots.nav }"
                >
                    <input
                        ref="search"
                        :value="search"
                        :placeholder="$t('Search')"
                        class="uk-search-input"
                        type="search"
                        autofocus
                        @input="(e) => $emit('update:search', e.target.value)"
                    />
                </div>
                <span
                    v-if="fetching"
                    key="spinner"
                    class="uk-margin-right-small"
                    uk-spinner="ratio: 0.5"
                ></span>
                <span
                    v-else-if="!$slots.nav"
                    key="search"
                    class="uk-search-icon-flip"
                    uk-search-icon
                ></span>
                <slot name="nav"></slot>
            </div>
        </div>

        <div :class="['yo-dropdown-body uk-overflow-auto', `uk-height-max-${maxHeight}`]">
            <ul v-if="entries.length" class="uk-nav uk-dropdown-nav">
                <template v-for="(group, label) in groups">
                    <li
                        v-if="!isFirstGroup(label)"
                        :key="`${label}-divider`"
                        class="uk-nav-divider"
                    ></li>
                    <li v-if="label" :key="`${label}-label`" class="uk-nav-header">{{ label }}</li>
                    <slot v-for="(entry, j) in group" name="entry" :entry="entry">
                        <li
                            v-if="entry.subgroup && group[j - 1]?.subgroup !== entry.subgroup"
                            :key="`${entry.value}-label`"
                            class="yo-nav-subheader"
                        >
                            {{ entry.subgroup }}
                        </li>
                        <li
                            :key="entry.value"
                            :class="{ 'uk-active': entry.value === selected }"
                            @click.prevent="$emit('resolve', entry)"
                        >
                            <a href class="uk-display-block">
                                <div class="uk-text-nowrap uk-text-truncate">{{ entry.text }}</div>
                                <div v-if="entry.meta" class="uk-text-meta uk-text-truncate">
                                    <span
                                        v-for="meta in prepareMeta(entry.meta)"
                                        :key="meta.value"
                                        class="uk-margin-small-right"
                                    >
                                        <b v-if="meta.text">{{ meta.text }}</b>
                                        <span>{{ meta.value }}</span>
                                    </span>
                                </div>
                            </a>
                        </li>
                    </slot>
                </template>
            </ul>

            <span v-else-if="fetching">...</span>
            <span v-else>{{ $t('No entries found.') }}</span>
        </div>
    </div>
</template>

<script>
import { groupBy } from '../util';
import { isObject } from 'uikit-util';

export default {
    name: 'DropdownList',

    props: {
        entries: {
            type: Array,
            default: () => [],
        },

        selected: {
            type: String,
        },

        search: {
            type: String,
        },

        maxHeight: {
            type: String,
            default: 'medium',
        },

        fetching: {
            type: Boolean,
            default: false,
        },
    },

    computed: {
        groups() {
            return groupBy(
                this.entries.map((entry) => ({ group: '', ...entry })),
                'group'
            );
        },
    },

    methods: {
        isFirstGroup(group) {
            return Object.keys(this.groups).indexOf(group) === 0;
        },

        prepareMeta(meta) {
            return !isObject(meta)
                ? [{ value: meta }]
                : Object.keys(meta).map((text) => ({ text, value: meta[text] }));
        },
    },
};
</script>
