<template>
	<view @click="toggle" class="evan-switch" :class="{'evan-switch--disabled':disabled}" :style="{width:2*size+'px',height:switchHeight,borderRadius:size+'px',backgroundColor:currentValue===activeValue?activeColor:inactiveColor}">
		<view class="evan-switch__circle" :style="{width:size+'px',height:size+'px',transform:currentValue===activeValue?`translateX(${size}px)`:`translateX(0)`}"></view>
	</view>
</template>

<script>
	export default {
		name: 'EvanSwitch',
		props: {
			value: {
				type: [String, Number, Boolean],
				default: false
			},
			activeColor: {
				type: String,
				default: '#108ee9'
			},
			inactiveColor: {
				type: String,
				default: '#fff'
			},
			size: {
				type: Number,
				default: 30
			},
			disabled: {
				type: Boolean,
				default: false
			},
			activeValue: {
				type: [String, Number, Boolean],
				default: true
			},
			inactiveValue: {
				type: [String, Number, Boolean],
				default: false
			},
			beforeChange: {
				type: Function,
				default: null
			},
			extraData: null,
			contextLevel: {
				type: Number,
				default: 1
			}
		},
		computed: {
			switchHeight() {
				// #ifdef APP-NVUE
				return this.size + 2 + 'px'
				// #endif
				// #ifndef APP-NVUE
				return this.size + 'px'
				// #endif
			}
		},
		watch: {
			value: {
				immediate: true,
				handler(value) {
					this.currentValue = value
				}
			}
		},
		data() {
			return {
				currentValue: false
			}
		},
		methods: {
			toggle() {
				if (!this.disabled) {
					if (this.beforeChange && typeof this.beforeChange === 'function') {
						let context = this
						for (let i = 0; i < this.contextLevel; i++) {
							context = context.$options.parent
						}
						const result = this.beforeChange(this.currentValue === this.activeValue ? this.inactiveValue : this.activeValue,
							this.extraData, context)
						if (typeof result === 'object') {
							result.then(() => {
								this.toggleValue()
							}).catch(() => {})
						} else if (typeof result === 'boolean' && result) {
							this.toggleValue()
						}
					} else {
						this.toggleValue()
					}
				}
			},
			toggleValue() {
				this.currentValue = this.currentValue === this.activeValue ? this.inactiveValue : this.activeValue
				this.$emit('input', this.currentValue)
				this.$emit('change', this.currentValue)
			}
		}
	}
</script>

<style lang="scss" scoped>
	.evan-switch {
		position: relative;
		border-width: 1px;
		border-color: rgba(0, 0, 0, 0.1);
		border-style: solid;
		transition: background-color 0.3s;
		/* #ifndef APP-NVUE */
		box-sizing: content-box;
		/* #endif */
	}

	.evan-switch--disabled {
		opacity: 0.3;
	}

	.evan-switch__circle {
		position: absolute;
		left: 0;
		top: 0;
		background-color: #fff;
		border-radius: 50%;
		/* #ifndef APP-NVUE */
		box-shadow: 0 3px 1px 0 rgba(0, 0, 0, 0.05), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 3px 3px 0 rgba(0, 0, 0, 0.05);
		/* #endif */
		/* #ifdef APP-NVUE */
		box-shadow: 1px 0 0px 0 rgba(0, 0, 0, 0.05);
		/* #endif */
		transition: transform 0.3s;
	}
</style>