<template>
    <div>
        <!-- the input field -->
        <input type="text"
               class="form-control"
               :placeholder="placeholder"
               autocomplete="off"
               :name="name"
               :value="query"
               v-model="query"
               @keydown.down="down"
               @keydown.up="up"
               @keydown.enter="enterHit"
               @keydown.esc="reset"
               @blur="reset"
               @input="update"/>

        <!-- optional indicators -->
        <i class="glyphicon glyphicon-refresh glyphicon-spin" v-if="loading"></i>
        <template v-else>
            <i class="glyphicon glyphicon-search" v-show="isEmpty"></i>
            <i class="glyphicon glyphicon-remove" v-show="isDirty" @click="resetForce"></i>
        </template>

        <!-- the list -->
        <ul v-show="hasItems">
            <!-- for vue@1.0 use: ($item, item) -->
            <li v-for="(item, $item) in items" :class="activeClass($item)" @mousedown="hit"
                @mousemove="setActive($item)">
                <span v-text="item.name"></span>
            </li>
        </ul>
        <!-- the list -->
        <ul v-show="reportNothing">
            <li @mousedown="resetForce">
                <span v-text="nothingString" class="text-danger text-center"></span>
            </li>
        </ul>
    </div>
</template>

<script>
    import VueTypeahead from 'vue-typeahead'

    const DELAY = 200

    import {delayer} from './utils.js'

    export default {
        extends: VueTypeahead, // vue@1.0.22+
        //mixins: [VueTypeahead], // vue@1.0.21-

        data () {
            return {

                // The data that would be sent by request
                // (optional)
                data: {
                    'limit': 20
                },

                query: null,

                // Limit the number of items which is shown at the list
                // (optional)
                limit: 20,

                // The minimum character length needed before triggering
                // (optional)
                minChars: 1,

                // Highlight the first item in the list
                // (optional)
                selectFirst: true,

                // Override the default value (`q`) of query parameter name
                // Use a falsy value for RESTful query
                // (optional)
                queryParamName: 'q',

                reportNothingTimeout: 2000,

                reportNothing: false
            }
        },
        props: {
            // ajax URL will be fetched
            src: {
                type: String,
                required: true
            },
            name: {
                type: String,
                required: true
            },
            placeholder: {
                type: String
            },
            nothingString: {
                type: String,
                required: true
            },
            query: {
                type: String,
                default: ''
            }
        },

        computed: {
            hasItems: function hasItems() {
                return this.items.length > 0;
            },
            isEmpty: function isEmpty() {
                return !this.query;
            },
            isDirty: function isDirty() {
                return !!this.query;
                //return !!this.query && !this.choosed;
            }
        },

        methods: {
            // The callback function which is triggered when the user hits on an item
            // (required)
            onHit (item) {
                this.choosed = true;
                this.items = [];
                this.query = item ? item.name : '';
                this.loading = false;
            },

            // The callback function which is triggered when the response data are received
            // (optional)
            prepareResponseData (data) {
                this.choosed = false;

                let _this = this;

                // Report nothing found ..
                if (data.length === 0) {
                    this.reportNothing = true;
                    setTimeout(function () {
                        _this.reportNothing = false;
                    }, this.reportNothingTimeout);
                }

                // data = ...
                return data;
            },

            enterHit(event) {
                this.reportNothing = false;
                if (!this.choosed) {
                    event.preventDefault();
                    return this.hit(event);
                }
            },
            update: delayer(function () {

                var _this = this;

                this.reportNothing = false;

                this.cancel();

                if (!this.query) {
                    return this.reset();
                }

                if (this.minChars && this.query.length < this.minChars) {
                    return;
                }

                this.loading = true;

                this.fetch().then(function (response) {
                    if (response && _this.query) {
                        var data = response.data;
                        data = _this.prepareResponseData ? _this.prepareResponseData(data) : data;
                        _this.items = _this.limit ? data.slice(0, _this.limit) : data;
                        _this.current = -1;
                        _this.loading = false;

                        if (_this.selectFirst) {
                            _this.down();
                        }
                    }
                });
            }, 'typeahead-delay', DELAY),
            reset: function reset() {
                this.reportNothing = false;
                this.items = [];
                if (!this.choosed)
                    this.query = '';
                this.loading = false;
            },
            resetForce: function resetForce() {
                this.choosed = false;
                this.reset();
            }
        }
    }
</script>

<style scoped>
    .Typeahead {
        position: relative;
    }

    .Typeahead__input {
        width: 100%;
        font-size: 14px;
        color: #2c3e50;
        line-height: 1.42857143;
        box-shadow: inset 0 1px 4px rgba(0, 0, 0, .4);
        -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
        transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
        font-weight: 300;
        padding: 12px 26px;
        border: none;
        border-radius: 22px;
        letter-spacing: 1px;
        box-sizing: border-box;
    }

    .Typeahead__input:focus {
        border-color: #4fc08d;
        outline: 0;
        box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px #4fc08d;
    }

    .glyphicon-remove {
        cursor: pointer;
    }

    i {
        float: right;
        position: relative;
        top: -24px;
        right: 7px;
        opacity: 0.4;
    }

    ul {
        position: absolute;
        padding: 0;
        margin-top: 8px;
        min-width: 92%;
        background-color: #fff;
        list-style: none;
        border-radius: 4px;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.25);
        z-index: 1000;
    }

    li {
        padding: 10px 16px;
        border-bottom: 1px solid #ccc;
        cursor: pointer;
    }

    li:first-child {
        border-top-left-radius: 4px;
        border-top-right-radius: 4px;
    }

    li:last-child {
        border-bottom-left-radius: 4px;
        border-bottom-right-radius: 4px;
        border-bottom: 0;
    }

    span {
        display: block;
        color: #2c3e50;
    }

    span.text-danger {
        color: #a94442;
    }

    .active {
        background-color: #3097D1;
    }

    .active span {
        color: white;
    }

    .name {
        font-weight: 700;
        font-size: 18px;
    }

    .screen-name {
        font-style: italic;
    }
</style>