<template>
<div class="buttonRadioCheckbox" :class="{'megaform': mega}">
    <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>
    <ul v-if="editable">
        <li v-for="i in opts" :key="i.id">
            <input :id="i.id" type="checkbox" :name="'MCB_'+id" class="butRC" :value="i.value" v-model="val" v-if="i.disabled" disabled/>
            <input :id="i.id" type="checkbox" :name="'MCB_'+id" class="butRC" :value="i.value" v-model="val" v-else/>
            <label :for="i.id" class="option">{{i.label}}</label>
        </li>
    </ul>
    <span v-if="!editable" class="noneditable" v-html="selLab"></span>
    <span v-show="editable && hasError" class="vldtn-error" v-html="message"></span>
</div>
</template>

<script>
import { isUndefined, isEmpty, uniqueId, find, delay, clone } from 'lodash'
import { shallowCopy } from '../../utils/utils.js'
/**
* Generates Checkbox buttons that can be independent or grouped.
*/
export default {
	name: 'CheckboxButtonGroup',
	inject: ['$validator'],
	props: {
        /**
        * Unique identifier
        */
		id: {
			default: 'MCB',
			type: String,
			required: true
		},
		title: String,
		mega: Boolean,
		rfq: Boolean,
		rfo: Boolean,
		aster: Boolean,
        /**
        * Options that need to be shown
        */
		options: {
			default: null
		},
        /**
        * Field that represents value
        */
		valueField: {
			default: 'value',
			type: String
		},
        /**
        * Field that represents label
        */
		labelField: {
			default: 'label',
			type: String
		},
        /**
        * Field that represents disabling
        */
		disabledField: {
			default: 'disabled',
			type: String
		},
        /**
        * Enables two way binding
        */
		value: {
			default: null
		},
        /**
        * Boolean flag to indicate readonly/editable controls
        */
		editable: {
			default: true
		},
        /**
        * Error message to be shown when invalid
        */
		message: {
			default: '',
			type: String
		}
	},
	$_veeValidate: {
		name() {
			return this.id
		},
		value() {
			return this.value
		}
	},
	created() {
		this.optCache = null
	},
	data() {
		return {
			val: [],
			opts: null
		}
	},
	computed: {
		selLab() {
			let l = []
			if (!isEmpty(this.opts)) {
				this.opts.forEach(o => {
					if (this.val.includes(o.value)) {
						l.push(o.label)
					}
				})
			}
			return l.join(', ')
		},
		hasError() {
			return !isEmpty(this.message)
		}
	},
	methods: {
		prepareOpts(obj) {
			this.opts = []
			if (isEmpty(obj)) {
				this.options.forEach((d) => {
					this.opts.push({
						id: uniqueId('MCBI'),
						value: d[this.valueField],
						label: d[this.labelField],
						disabled: d[this.disabledField]
					})
				})
			} else {
				obj.forEach((d) => {
					this.opts.push({
						id: uniqueId('MCBI'),
						value: d[this.valueField],
						label: d[this.labelField],
						disabled: d[this.disabledField]
					})
				})
			}
			this.chooseOption(this.value)
			this.optCache = obj || shallowCopy(this.options)
		},
		chooseOption(n) {
			this.val = n
		}
	},
	mounted() {
		if (!isEmpty(this.options)) {
			this.prepareOpts()
		}
		this.$events.on(`checkboxbutton|${this.id}`, (d) => {
			// Change of options task
			if (d.task.toLowerCase() == 'option') {
				this.prepareOpts(d.val)
			} else if (d.task.toLowerCase() == 'item') { // This is for changing the selected values
				this.chooseOption(d.val)
			} else if (d.task.toLowerCase() == 'control') {
				let opts = clone(this.optCache)
				opts.forEach(o => {
					if (isUndefined(o[this.disabledField])) {
						o.disabled = d.val.toLowerCase() === 'disable'
					} else {
						o[this.disabledField] = d.val.toLowerCase() === 'disable'
					}
				})
				this.opts = []
				delay(() => {
					this.prepareOpts(opts)
				}, 100)
			}
		})
	},
	beforeDestroy() {
		this.$events.off(`checkboxbutton|${this.id}`)
	},
	watch: {
		options(n, o) {
			this.prepareOpts(n)
		},
		value(n, o) {
			this.chooseOption(n)
		},
		val(n, o) {
			this.$emit('input', n)
		}
	}
}
</script>
