<template>
	<div class="autocomplete">
		<input type="text" @input="option_open" v-model="xvalue" @keydown.down="option_down" @keydown.up="option_up" @keydown.enter="option_enter" />
		<ul id="autocomplete-results" v-show="open" class="autocomplete-results">
			<li class="loading" v-if="!items">Loading results...</li>
			<li v-else v-for="(result, i) in results" :key="i" @click="option_click(result)" class="autocomplete-result" :class="{ 'is-active': i === index }">{{ result }}</li>
		</ul>
	</div>
</template>

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

	.autocomplete-results {
		padding: 0;
		margin: 0;
		border: 1px solid #eeeeee;
		height: 120px;
		overflow: auto;
	}

	.autocomplete-result {
		list-style: none;
		text-align: left;
		padding: 4px 2px;
		cursor: pointer;
	}

	.autocomplete-result.is-active,
	.autocomplete-result:hover {
		background-color: #4AAE9B;
		color: white;
	}
</style>

<script>
	export default {
		props: {
			value: {
				type: String,
				default: ''
			},
			items: {
				type: Array,
				required: false,
				default: () => [],
			}
		},
		data() {
			return {
				xvalue: '',
				results: [],
				open: false,
				index: -1,
			};
		},
		watch: {
			value(val) {
				this.xvalue = val;
			},
			xvalue(val) {
				this.$emit('update:value', val);
			}
		},
		mounted() {
			this.xvalue = this.value;
			document.addEventListener('click', this.option_close)
		},
		destroyed() {
			document.removeEventListener('click', this.option_close)
		},
		methods: {
			option_open() {
				if(this.items) {
					this.results = this.items.filter((item) => item.toLowerCase().indexOf(this.xvalue.toLowerCase()) > -1);
					this.open = true;
				}
			},
			option_down() {
				if(this.index < this.results.length) this.index++;
			},
			option_up() {
				if(this.index > 0) this.index--;
			},
			option_enter() {
				this.xvalue = this.results[this.index];
				this.open = false;
				this.index = -1;
			},
			option_click(result) {
				this.xvalue = result;
				this.open = false;
			},
			option_close(evt) {
				if(!this.$el.contains(evt.target)) {
					this.open = false;
					this.index = -1;
				}
			}
		}
	};
</script>
