<template>
<div class="stepperWarp" :style="{'width': wrapperWidth, 'height': wrapperHeight}">
    <ul class="blobWrap horizontal" v-if="type == 'horizontal' && list.length" :style="progressiveBackground" ref="rail">
        <li v-for="(s, idx) in list" :key="idx" :style="{left: blobPos(idx)}">
            <div class="blob" :class="s.color" @click="emitEvent(s.code, s.color)">
                <Icon v-if="!emptyBlob && checkFAIconType(s.icon)" :icon="s.icon" class="icon"/>
                <span v-if="!emptyBlob && !checkFAIconType(s.icon)">{{ s.icon }}</span>
            </div>
            <span class="details">{{ s.title }}</span>
        </li>
    </ul>
    <ul class="blobWrap vertical" :class="{'right': type.contains('right')}" v-if="type.contains('vertical') && list.length" :style="progressiveBackground" ref="rail">
        <li v-for="(s, idx) in list" :key="idx" :style="{top: blobPos(idx)}">
            <div class="blob" :class="s.color">
                <Icon v-if="!emptyBlob && checkFAIconType(s.icon)" :icon="s.icon" class="icon"/>
                <span v-if="!emptyBlob && !checkFAIconType(s.icon)">{{ s.icon }}</span>
            </div>
            <span class="details">{{ s.title }}</span>
        </li>
    </ul>
</div>
</template>

<script>
import { isEmpty, isArray } from 'lodash'
import { FontAwesomeIcon as Icon } from '@fortawesome/vue-fontawesome'

export default {
	name: 'Stepper',
	components: {
		Icon
	},
	props: {
		id: {
			type: String,
			default: 'STEPPER'
		},
		config: {
			required: true,
			type: Array
		},
		type: {
			type: String,
			default: 'horizontal',
			validate: function (val) {
				return ['horizontal', 'vertical', 'vertical-left', 'vertical-right'].includes(val)
			}
		},
		titleField: {
			type: String,
			default: 'title'
		},
		iconField: {
			type: String,
			default: 'icon'
		},
		colorField: {
			type: String,
			default: 'color'
		},
		codeField: {
			type: String,
			default: 'code'
		},
		emptyBlob: {
			type: Boolean,
			default: false
		},
		progressive: {
			type: Boolean,
			default: false
		},
		progress: {
			type: Number,
			default: 100
		},
		width: {
			type: String,
			default: null
		},
		height: {
			type: String,
			default: null
		}
	},
	data() {
		return {
			list: [],
			titles: []
		}
	},
	computed: {
		wrapperWidth() {
			return this.width ? this.width : (this.type == 'horizontal' ? '90%' : '50px')
		},
		wrapperHeight() {
			return this.height ? this.height : (this.type == 'horizontal' ? '50px' : '90%')
		},
		blobCords() {
			let parts = [0]
			let pos = 0
			let part = this.list.length > 1 ? 100 / (this.list.length - 1) : 100
			for (let i = 0; i < this.list.length - 2; i++) {
				pos += part
				parts.push(pos)
			}
			parts.push(100)
			return parts
		},
		progressiveBackground() {
			if (this.progressive) {
				return this.bgColor(this.type == 'horizontal' ? 'right' : 'bottom', this.progress)
			} else {
				return 'background: #6400AA'
			}
		}
	},
	methods: {
		blobPos(index) {
			return `${this.blobCords[index] - 1.5}%`
		},
		checkFAIconType(g) {
			return isArray(g)
		},
		bgColor(dir, percent) {
			if (percent == 100) {
				return `background: linear-gradient(to ${dir}, #51CB20 0%, #51CB20 100%)`
			} else if (percent < 10) {
				return `background: linear-gradient(to ${dir}, #FFBF00 10%, #000 20%, #000 100%)`
			} else if (percent > 95 && percent < 100) {
				return `background: linear-gradient(to ${dir}, #51CB20 95%, #FFBF00 100%);`
			} else {
				return `background: linear-gradient(to ${dir}, #51CB20 ${percent}%, #FFBF00 1%, #000 100%)`
			}
		},
		initStepper() {
			this.titles = []
			if (!isEmpty(this.config)) {
				let steps = []
				let count = 1
				this.config.forEach(d => {
					if (!isEmpty(d)) {
						steps.push({
							title: d[this.titleField] || '',
							color: d[this.colorField] || 'white',
							icon: null,
							code: d[this.codeField] || count
						})
						this.titles.push(d[this.titleField] || '')
						count++
					}
				})
				this.list = steps
			} else {
				console.warn('[StepperWarn]: Please pass valid configuration to the component.')
			}
		},
		emitEvent(code, color) {
			this.$emit('selected', { code, color })
		}
	},
	watch: {
		config: {
			deep: true,
			immediate: true,
			handler: 'initStepper'
		},
		progress: {
			immediate: true,
			handler: 'initStepper'
		}
	}
}
</script>
