<template>
    <div class="dropdown" :class="{'open': open}">
        <div class="input-group">
            <input type="text" class="form-control" v-model="searchText" @input="searchChanged">
            <div class="form-group-append">
                <a class="toggle input-group-text bg-primary text-light" @mousedown.prevent @click="setOpen(!open)">
                    <span class="arrow-up">▲</span>
                    <span class="arrow-down">▼</span>
                </a>
            </div>
        </div>
        <ul class="suggestion-list list-unstyled">
            <li v-for="(suggestion,index) in matches" :key="index"
                @mousedown.prevent
                @click="suggestionSelected(suggestion)"
            >
                {{ suggestion[1] }}
            </li>
        </ul>
    </div>
</template>
<script>
export default {
    props: {
        value: null,
        // An object with the following format
        // {
        //     key: value,
        //     key: value,
        // }
        options: {
            type: Object,
            required: true
        },
        allowCustom: {
            type: Boolean,
            default: false
        }
    },
    data () {
        return {
            searchText: '',
            selectedOption: null,
            open: false,
            // allows for checking whether button was clicked or text was typed.
            // If button was clicked, we show all options without having to clear
            // out any searchText that was autofilled when page loaded.
            isSearching: false
        }
    },
    computed: {
        matches () {
            // If button was clicked, show all options, if typing, filter
            // options based on searchText
            return Object.entries(this.options).filter((option) => {
                var optionText = option[1].toUpperCase()
                if (this.isSearching) {
                    return optionText.match(this.searchText.toUpperCase())
                }
                else {
                    return optionText.match('')
                }
            })
        }
    },
    methods: {
        // if button is clicked, show all options
        setOpen (isOpen) {
            this.open = isOpen
            this.isSearching = false
        },
        // if typing in the box, start filtering options
        searchChanged () {
            if (!this.open) {
                this.open = true
            }
            if (!this.isSearching) {
                this.isSearching = true
            }

            // If custom values are allowed, emits {id: 'custom', name: searchtext}
            if (this.allowCustom) {
                this.$emit('input', {'id': 'custom', 'name': this.searchText})
            }
        },
        // emits { id: suggestion_id, name: suggestion_name} to v-model when 
        // a suggestion is selected
        suggestionSelected (suggestion) {
            this.open = false
            this.searchText = suggestion[1]
            this.$emit('input', { 'id': suggestion[0], 'name': suggestion[1]})
        },
        updateComponentWithValue(newValue) {
            if (this.allowCustom) {
                this.searchText = this.value.name
            }
            else {
                if (newValue.id > -1) {
                    // Find the matching text for the supplied option value
                    for (var id in this.options) {
                        if (this.options.hasOwnProperty(id)) {
                            if (this.options[id] === this.options[newValue.id]) {
                                this.searchText = this.options[id]
                            }
                        }
                    }
                }
            }
        }
    },
    mounted () {
        this.updateComponentWithValue(this.value)
    },
    watch: {
        value: function (newValue) {
            this.updateComponentWithValue(newValue)
        }
    }
}
</script>