<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>
    <input
      type="tel"
      v-model="inputValue" 
      :placeholder="placeholder ? placeholder : label" 
      :minlength="minLength ? minLength : ''"
      :maxlength="maxLength ? maxLength : ''"
      :class="{ 
        'error': isValid == false, 
        'good': isValid == true
      }"
      @blur="validate"
      @keydown="characterBlocking($event)"
      @keyup="applyFormatting($event)"
      @focus="isValid = null"
    >
    <p class="error-message">{{ validationMessage }}</p>

    <template v-if="calculation !== undefined">
      <span class="info-message supporting-below" 
        v-show="unformatCurrency(inputValue) > 0" 
        v-html="calculation(inputValue, formatCurrency)"></span>
    </template>

    <template v-if="lowAmount !== undefined && isValid === true">
      <span class="info-message supporting-below warning" v-show="lowAmount.value >= unformatCurrency(inputValue)">
          {{ lowAmount.message }}
      </span>
    </template>
  </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: 'currencyinput',
  props: {
    inputname: {
      type: String,
      required: true
    },
    label: String,
    required: Boolean,
    minLength: Number,
    maxLength: Number,
    minValue: Number,
    maxValue: Number,
    lowAmount: Object,
    value: Object,
    placeholder: String,
    helpText: String,
    sectionID: Number,
    calculation: Function,
    customErrors: {
      type: Object,
      default: function () { 
        return {
          required: null,
          minLength: null,
          maxLength: null,
          minValue: null,
          maxValue: null
        }
      }
    }
  },
  mixins: [validation],
  data() {
    return {
      inputValue: '',
      isValid: null
    }
  },
  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.formatCurrency(this.value.value)
    }
  },
  mounted() {
    // if prepopulating validate the data
    if (this.value !== undefined) {
      this.validate('prepopulated')
    }
  },
  methods: {
    emitValue: function(type){
      // emit validated event
      this.$emit(type, { 
        'value': this.unformatCurrency(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_currency(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,
          this.minValue ? vRules.vrule_minValue(elm, this.minValue, this.customErrors.minValue): true,
          this.maxValue ? vRules.vrule_maxValue(elm, this.maxValue, this.customErrors.maxValue): 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)
    },
    characterBlocking: function (event) {
      this.blockDecimals(event)
      this.blockNonNumerical(event)
    },
    blockDecimals: function (event) {
      event = event || window.event;
      var charCode = (typeof event.which == "undefined") ? event.keyCode : event.which;
      if (charCode == 190)
          event.preventDefault()
    },
    blockNonNumerical: function (event) {
      event = event || window.event;
      const charCode = (typeof event.which == "undefined") ? event.keyCode : event.which;
      const charStr = String.fromCharCode(charCode);

      if (charCode == 32 || /[a-zA-Z]/.test(charStr))
        if (charCode != 97 && charCode != 98 && charCode != 99 && charCode != 100 && charCode != 101 && charCode != 102 && charCode != 103 && charCode != 104 && charCode != 105)
            event.preventDefault()
    },
    applyFormatting: function (event) {
      event = event || window.event;
      const charCode = (typeof event.which == "undefined") ? event.keyCode : event.which;
      // block formatting on delete key unless the value length more than 2 (£0)
      // block formatting on tabkey
      if ((charCode != 9 && charCode != 46 && charCode != 8) || event.target.value.length >= 2)
        this.inputValue = this.formatCurrency(event.target.value)
    },
    unformatCurrency: function (value) {
      if (isNaN(value)) {
        let unformatted = value.replace("£", "").replace(/,/g, "")
        return Number(unformatted)
      } else {
        return value
      }
    },
    formatCurrency: function (value) {
      let numValue = this.unformatCurrency(value)
      if (isNaN(numValue)) {
        return '£'
      }

      let formatted = '£' + parseFloat(numValue).toFixed(0).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
      return formatted
    }
  }
}
</script>
