<template>
    <div class="mt-1 relative rounded-sm shadow-sm"
         @keydown.escape="hideResults"
    >
        <!-- Fix for the click away event to force close -->
        <div
            v-if="open"
            @click="hideResults"
            class="fixed inset-0"
            tabindex="-1"
        ></div>

        <!-- Search input -->
        <input class="form-input block w-full rounded-sm sm:text-sm sm:leading-5"
               type="text"
               :placeholder="placeholder"
               :name="name"
               v-model="searchQuery"
               @keyup="search"
               @keydown.enter.prevent='enter'
               @keydown.down.prevent='down'
               @keydown.up.prevent='up'
               debounce="500"
               autocomplete="off"
        />

        <!-- Search dropdown -->
        <transition
            enter-active-class="transition ease-out duration-100"
            enter-class="transform opacity-0 scale-95"
            enter-to-class="transform opacity-100 scale-100"
            leave-active-class="transition ease-in duration-75"
            leave-class="transform opacity-100 scale-100"
            leave-to-class="transform opacity-0 scale-95"
        >
            <div v-if="open" class="origin-top-right absolute mt-1 z-10 w-full">
                <ul class="text-base leading-6 bg-white rounded-sm border border-gray-300 focus:outline-none shadow-xl max-h-60 overflow-auto py-1 md:text-sm md:leading-5"
                    tabindex="-1"
                >
                    <li v-for="(item, index) in items"
                        class="cursor-default select-none relative py-2 pl-3 pr-9 cursor-pointer"
                        :class="isSelected(item, index) ? 'bg-gray-600 text-white' : 'text-gray-900 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900'"
                        @click="setAsSelected(item, index)"
                    >
                        <span class="font-normal block truncate">
                            {{ item.name }}
                        </span>
                        <span v-if="isSelected(item, index)"
                              class="text-white absolute inset-y-0 right-0 flex items-center pr-4"
                        >
                            <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
                                <path fill-rule="evenodd"
                                      d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
                                      clip-rule="evenodd"
                                />
                            </svg>
                        </span>
                    </li>
                </ul>
            </div>
        </transition>

    </div>
</template>


<script>
export default {
    props : {
        name : {
            required : true
        },
        value : {
            default : null
        },
        placeholder : {
            type : String,
            default : 'Type to Search...'
        },
        url : {
            required : true
        },
        params : {
            type : Object,
            default : () => {
            }
        },
        orderBy : {
            default : 'name',
        },
        orderDirection : {
            default : 'asc',
        },
    },
    data() {
        return {
            open : false,
            searchQuery : null,
            selected : 0,
            items : []
        }
    },
    methods : {
        showResults() {
            return this.open = true;
        },
        hideResults() {
            return this.open = false;
        },
        getParams() {
            return {
                search : this.searchQuery,
                order_by : this.orderBy,
                order_direction : this.orderDirection,
                ...this.params
            };
        },
        search(e) {
            switch (e.keyCode) {
                case 37: // left
                case 38: // up
                case 39: // right
                case 40: // down
                    return;
            }

            window.axios
                .get(this.url, {params : this.getParams()})
                .then((response) => {
                    if (!response.data.results.length) {
                        return this.hideResults();
                    }
                    this.items = response.data.results;
                    this.showResults();
                })
                .catch(e => {
                    console.log(e);
                });
        },
        enter() {
            this.searchQuery = this.items[this.selected].name;
            this.hideResults();
        },
        up() {
            if (this.selected > 0) {
                this.selected--;
            }
        },
        down() {
            if (this.selected < this.items.length - 1) {
                this.selected++;
            }
        },
        isSelected(item, index) {
            return index === this.selected;
        },
        setAsSelected(item, index) {
            this.selected = index;
            this.searchQuery = this.items[index].name;
            this.$emit('selected', this.searchQuery);
            this.hideResults();
        }
    },
    watch : {
        value : function (newValue, oldValue) {
            this.searchQuery = newValue;
        }
    },
    mounted() {
        if (this.value) {
            this.searchQuery = this.value;
        }
    }
}
</script>
