<template>
    <div :class="dropdownClass">
        <div class="dropdown-trigger is-fullwidth">
            <div class="control is-expanded">
                <input type="hidden" :name="name"
                    :value="selectedValue" />
                <input type="text" :placeholder="placeholder"
                    ref="input" class="input is-fullwidth"
                    @keyup="onKeyUp" @focus="active=true" @click="active=true"/>
            </div>
        </div>
        <div class="dropdown-menu is-fullwidth">
            <div class="dropdown-content" style="overflow: hidden">
                <a v-for="(item, index) in items" :key="item.id"
                    :class="['dropdown-item', index === this.selectedIndex ? 'is-active':'']"
                    @click="select(index); active=false" :title="item.data[labelField]">
                    <slot name="item" :index="index" :item="item" :value-field="valueField"
                        :labelField="labelField">
                    {{ item.data[labelField] }}
                    </slot>
                </a>
            </div>
        </div>
    </div>
</template>

<script>
// import debounce from 'lodash/debounce'

export default {
    props: {
        url: String,
        model: Function,
        placeholder: String,
        name: String,
        labelField: String,
        valueField: {type: String, default: null},
        count: {type: Number, count: 10},
    },

    data() {
        return {
            active: false,
            value: '',
            items: [],
            selectedIndex: -1,
            isFetching: false,
        }
    },

    computed: {
        selected() {
            let index = this.selectedIndex
            if(index<0)
                return null
            index = Math.min(index, this.items.length-1)
            return this.items[index]
        },
        
        selectedValue() {
            const sel = this.selected
            return sel && (this.valueField ?
                    sel.data[this.valueField] : sel.id)
        },

        selectedLabel() {
            const sel = this.selected
            return sel && sel.data[this.labelField]
        },

        dropdownClass() {
            const active = this.active && this.items.length;
            return ['dropdown', active ? 'is-active':'']
        },
    },

    methods: {
        select(index, relative) {
            if(relative)
                index += this.selectedIndex
            else if(index == this.selectedIndex)
                return
        
            this.selectedIndex =  Math.max(-1, Math.min(index, this.items.length-1))
            if(index >= 0) {
                this.$refs.input.value = this.selectedLabel
                this.$refs.input.focus()
            }
            this.$emit('select', index, this.selected, this.selectedValue)
        },

        onKeyUp: function(event) {
            this.active = true
            switch(event.keyCode) {
                case 27: this.active = false
                         return
                case 38: this.select(-1, true)
                         return
                case 40: this.select(1, true)
                         return
            }


            const value = event.target.value
            if(value === this.value)
                return

            this.value = value;
            if(!value)
                return this.select(null)

            this.fetch(value)
        },

        fetch: function(query) {
            if(!query || this.isFetching)
                return

            this.isFetching = true
            return this.model.fetch(this.url.replace('${query}', query), {many:true})
                .then(items => { this.items = items || []
                                 this.isFetching = false
                                 this.active = items.length > 0
                                 return items },
                      data => {this.isFetching = false; Promise.reject(data)})
        },
    },
}

</script>

