<template>
<div :class="divClass">
    <label v-if="mega">{{title}}<span class="rfo" v-if="rfo">*</span><span class="rfq" v-if="rfq">*</span><span class="aster" v-if="aster">*</span></label>
    <input :id="id" :ref="id" :class="hasError && !mega ? 'invalid' : 'text'" :type="inputType" :value="value" @input="emitInput" @blur="emitBlur" @focus="captureFocus" v-if="editable && readonly" :placeholder="placeholder" :data-attr-err="errLabel" disabled="disabled">
    <input :id="id" :ref="id" :class="hasError && !mega ? 'invalid' : 'text'" :type="inputType" :value="value" @input="emitInput" @blur="emitBlur" @focus="captureFocus" v-if="editable && !readonly" :placeholder="placeholder" :data-attr-err="errLabel" @keypress="emitEvents('keypress')" @keypress.enter="emitEvents('keyenter')" @keyup="emitEvents('keyup')" @keydown="emitEvents('keydown')">
    <Icon v-if="editable && inputType == 'password'" :icon="['fabt', !passwordToggle ? 'eye' : 'eye-slash']" class="icon" @click="passwordToggle = !passwordToggle" :title="$t('btgsvue.toggleVisible')"/>
    <span v-if="!editable" class="noneditable">{{value}}</span>
    <span v-show="editable && hasError" class="vldtn-error" v-html="message"></span>
</div>
</template>

<script>
import { isEmpty, defer } from 'lodash'
import { FontAwesomeIcon as Icon } from '@fortawesome/vue-fontawesome'
export default {
	name: 'TextInput',
	inject: ['$validator'],
	props: {
		// Unique identifier
		id: {
			default: 'INPUT_',
			type: String,
			required: true
		},
		// Type of the input feild
		type: {
			type: String,
			default: 'text',
			validator: function (val) {
				return ['url', 'text', 'password', 'email', 'search'].indexOf(val) !== -1
			}
		},
		// Value binding for the component
		value: {
			default: null
		},
		// Label text for mega display
		title: {
			default: 'Enter value',
			type: String
		},
		// Error message to be shown when invalid
		message: {
			default: '',
			type: String
		},
		// Boolean flag to indicate editable state or not. Displays label instead of input box. Do not confuse this with read only field.
		editable: {
			default: true,
			type: Boolean
		},
		// Mobile compatible material style input
		mega: {
			default: false,
			type: Boolean
		},
		// Required for order style
		rfo: {
			default: false,
			type: Boolean
		},
		// Required for Quote style
		rfq: {
			default: false,
			type: Boolean
		},
		// Show aster mark
		aster: {
			default: false,
			type: Boolean
		},
		// Text value to be shown as placeholder
		placeholder: {
			type: String,
			default: ''
		},
		// Boolean flag to indicate input is readonly even when editable.
		readonly: {
			type: Boolean,
			default: false
		},
		// This helps to get the label/id when validation error occurs directly from DOM
		dataAttrErr: {
			type: String,
			default: ''
		}
	},
	$_veeValidate: {
		name() {
			return this.id
		},
		value() {
			return this.value
		}
	},
	components: {
		Icon
	},
	computed: {
		divClass() {
			let cls = ['text-input']
			if (this.mega) {
				cls.push('megaform')
			}
			if (this.focused) {
				cls.push('focus')
			}
			if (this.hasError) {
				cls.push('error')
			}
			if (this.readonly) {
				cls.push('readonly')
			}
			return cls.join(' ')
		},
		hasError() {
			return !isEmpty(this.message)
		}
	},
	data() {
		return {
			errLabel: '',
			inputType: 'text',
			focused: false,
			passwordToggle: false
		}
	},
	methods: {
		emitInput(e) {
			// Alternative this.$refs[this.id].value or e.target.value
			this.$emit('input', this.$refs[this.id].value)
			if (!this.focused) {
				this.$emit('change', this.$refs[this.id].value)
			}
		},
		emitBlur(e) {
			this.focused = false
			this.$emit('blur', this.value)
		},
		emitEvents(e) {
			this.$emit(e)
		},
		captureFocus(e) {
			this.focused = true
		}
	},
	mounted() {
		this.errLabel = isEmpty(this.dataAttrErr) ? this.id : this.dataAttrErr
		this.inputType = this.type
	},
	watch: {
		passwordToggle(n, o) {
			this.$refs[this.id].setAttribute('type', n ? 'text' : 'password')
		},
		editable: {
			immediate: true,
			handler: function (n) {
				if (n) {
					this.$validator.resume()
				} else {
					this.$validator.pause()
				}
			}
		}
	}
}
</script>
