<template>
  <div class="question" v-bind:class="{ 
      'error': isValid == false, 
      'good': isValid == true
    }">
    <label v-show="label !== null && label !== ''">{{ label }}</label>
    <span class="info-message" v-if="helpText !== undefined">{{ helpText }}</span>
    <div class="autocomplete">
      <input
        v-model="inputValue" 
        ref="input"
        :placeholder="placeholder ? placeholder : label" 
        :minlength="minLength ? minLength : ''"
        :maxlength="maxLength ? maxLength : ''"
        :class="{ 
          'error': isValid == false, 
          'good': isValid == true
        }"
        @blur="validate"
        @focus="isValid = null"
      >
    </div>
    <p class="error-message">{{ validationMessage }}</p>
  </div>
</template>

<script>
// create event hub for validation events
import Vue from 'vue'
//import EventHub from 'vue-event-hub'
//Vue.use(EventHub)

import vRules from 'vanilla-validation'

import { validation } from '../mixins/validation.js'

export default {
  name: 'autoComplete',
  props: {
    inputname: {
      type: String,
      required: true
    },
    label: String,
    required: Boolean,
    value: Object,
    minLength: Number,
    maxLength: Number,
    helpText: String,
    placeholder: String,
    sectionID: Number,
    autocompleteOptions: Array,
    customErrors: {
      type: Object,
      default: function () { 
        return {
          required: null,
          minLength: null,
          maxLength: null
        }
      }
    }
  },
  mixins: [validation],
  data() {
    return {
      inputValue: '',
    }
  },
  created() {
    // We listen for the event on the eventHub
    this.$eventHub.on('validate', (id) => {
      // if validating by section
      if (this.sectionID != undefined) {
          // if the id provided matches section ID then validate
          if (id === this.sectionID) {
            this.validate()
          }
      } else {
        // if not validating by section
        this.validate()
      }
    })
    // if prepopulating set data
    if (this.value !== undefined) {
        this.inputValue = this.value.value
    }
  },
  mounted() {
    // if prepopulating validate the data
    if (this.value !== undefined) {
        this.validate('prepopulated')
    }

    // setup autocomplete listener
    this.autocomplete(this.$refs.input, this.autocompleteOptions)
  },
  methods: {
    autocomplete: function(inp, arr) {
        let self = this
        /*the autocomplete function takes two arguments,
        the text field element and an array of possible autocompleted values:*/
        var currentFocus;
        /*execute a function when someone writes in the text field:*/
        inp.addEventListener("input", function(e) {
            var a, b, i, val = this.value;
            /*close any already open lists of autocompleted values*/
            self.closeAllLists();
            if (!val) { return false;}
            currentFocus = -1;
            /*create a DIV element that will contain the items (values):*/
            a = document.createElement("DIV");
            a.setAttribute("id", this.id + "autocomplete-list");
            a.setAttribute("class", "autocomplete-items");
            /*append the DIV element as a child of the autocomplete container:*/
            this.parentNode.appendChild(a);
            /*for each item in the array...*/
            for (i = 0; i < arr.length; i++) {
                /*check if the item starts with the same letters as the text field value:*/
                if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
                    /*create a DIV element for each matching element:*/
                    b = document.createElement("DIV");
                    /*make the matching letters bold:*/
                    b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
                    b.innerHTML += arr[i].substr(val.length);
                    /*insert a input field that will hold the current array item's value:*/
                    b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
                    /*execute a function when someone clicks on the item value (DIV element):*/
                    b.addEventListener("click", function(e) {
                        /*insert the value for the autocomplete text field:*/
                        self.inputValue = this.getElementsByTagName("input")[0].value;
                        /*close the list of autocompleted values,
                        (or any other open lists of autocompleted values:*/
                        self.closeAllLists();
                    });
                    a.appendChild(b);
                }
            }
        })
    },
    closeAllLists: function(elmnt) {
      /*close all autocomplete lists in the document,
      except the one passed as an argument:*/
      var x = document.getElementsByClassName("autocomplete-items");
      for (var i = 0; i < x.length; i++) {
        if (elmnt != x[i] && elmnt != this.$refs.input) {
            x[i].parentNode.removeChild(x[i]);
        }
      }
    },
    emitValue: function(type){
      // emit validated event
      this.$emit(type, { 
        'value': this.inputValue, 
        'name': this.inputname, 
        'isValid': this.isValid 
      })
    },
    validate: function(type) {
      let elm = this.$el.querySelector('input')
      // check what validations are required
      // and build and array of booleans (these are then checked to see if input is valid)
      let result = [
        // default input type validation rule
        vRules.vrule_textInput(elm),
        // conditional validation rules
        this.required ? vRules.vrule_required(elm, this.customErrors.required) : true,
        this.minLength ? vRules.vrule_minLength(elm, this.minLength, this.customErrors.minLength) : true,
        this.maxLength ? vRules.vrule_maxLength(elm, this.maxLength, this.customErrors.maxLength) : true,
      ]
      
      // check validation result
      // this function is imported from validation mixin
      // if will set the valid status and error message
      this.setValidationStatus(result)

      // default the type to 'validated' if not using prepopulated event type
      let emitType = type !== 'prepopulated' ? 'validated' : type
      // emit the updated value to parent
      this.emitValue(emitType)
    }
  }
}
</script>

<style>
.autocomplete {
  position: relative;
}

.autocomplete-items {
  position: absolute;
  z-index: 99;
  /*position the autocomplete items to be the same width as the container:*/
  top: 100%;
  left: 0;
  right: 0;
}
.autocomplete-items div {
  padding: 10px;
  cursor: pointer;
  background-color: #fff; 
  /*border-bottom: 1px solid #d4d4d4;*/
  text-align: left; 
}
.autocomplete-items div:hover {
  /*when hovering an item:*/
  background-color: #e9e9e9; 
}
.autocomplete-active {
  /*when navigating through the items using the arrow keys:*/
  background-color: DodgerBlue !important; 
  color: #ffffff; 
}
</style>