<template>
	<view class="mpvue-picker">
		<view
			:class="{ pickerMask: showPicker }"
			@tap="maskClick"
			catchtouchmove="true"
		></view>
		<view
			class="mpvue-picker-content "
			:class="{ 'mpvue-picker-view-show': showPicker }"
		>
			<view class="mpvue-picker__hd" catchtouchmove="true">
				<view class="mpvue-picker__action" @tap="pickerCancel">取消</view>
				<view
					class="mpvue-picker__action"
					:style="{ color: themeColor.color }"
					@tap="pickerConfirm"
					>确定</view
				>
			</view>
			<!-- 单列 -->
			<picker-view
				indicator-style="height: 40px;"
				class="mpvue-picker-view"
				:value="pickerValue"
				@change="pickerChange"
				v-if="mode === 'selector' && pickerValueSingleArray.length > 0"
			>
				<block>
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index) in pickerValueSingleArray"
							:key="index"
							>{{ item.label }}</view
						>
					</picker-view-column>
				</block>
			</picker-view>
			<!-- 时间选择器 -->
			<picker-view
				indicator-style="height: 40px;"
				class="mpvue-picker-view"
				:value="pickerValue"
				@change="pickerChange"
				v-if="mode === 'timeSelector'"
			>
				<block>
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index) in pickerValueHour"
							:key="index"
							>{{ item.label }}</view
						>
					</picker-view-column>
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index) in pickerValueMinute"
							:key="index"
							>{{ item.label }}</view
						>
					</picker-view-column>
				</block>
			</picker-view>
			<!-- 多列选择 -->
			<picker-view
				indicator-style="height: 40px;"
				class="mpvue-picker-view"
				:value="pickerValue"
				@change="pickerChange"
				v-if="mode === 'multiSelector'"
			>
				<block v-for="(n, index) in pickerValueMulArray.length" :key="index">
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index1) in pickerValueMulArray[n]"
							:key="index1"
							>{{ item.label }}</view
						>
					</picker-view-column>
				</block>
			</picker-view>
			<!-- 二级联动 -->
			<picker-view
				indicator-style="height: 40px;"
				class="mpvue-picker-view"
				:value="pickerValue"
				@change="pickerChangeMul"
				v-if="mode === 'multiLinkageSelector' && deepLength === 2"
			>
				<block>
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index) in pickerValueMulTwoOne"
							:key="index"
							>{{ item.label }}</view
						>
					</picker-view-column>
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index) in pickerValueMulTwoTwo"
							:key="index"
							>{{ item.label }}</view
						>
					</picker-view-column>
				</block>
			</picker-view>
			<!-- 三级联动 -->
			<picker-view
				indicator-style="height: 40px;"
				class="mpvue-picker-view"
				:value="pickerValue"
				@change="pickerChangeMul"
				v-if="mode === 'multiLinkageSelector' && deepLength === 3"
			>
				<block>
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index) in pickerValueMulThreeOne"
							:key="index"
							>{{ item.label }}</view
						>
					</picker-view-column>
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index) in pickerValueMulThreeTwo"
							:key="index"
							>{{ item.label }}</view
						>
					</picker-view-column>
					<picker-view-column>
						<view
							class="picker-item"
							v-for="(item, index) in pickerValueMulThreeThree"
							:key="index"
							>{{ item.label }}</view
						>
					</picker-view-column>
				</block>
			</picker-view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			pickerChangeValue: [],
			pickerValue: [],
			pickerValueArrayChange: true,
			modeChange: false,
			pickerValueSingleArray: [],
			pickerValueHour: [],
			pickerValueMinute: [],
			pickerValueMulArray: [],
			pickerValueMulTwoOne: [],
			pickerValueMulTwoTwo: [],
			pickerValueMulThreeOne: [],
			pickerValueMulThreeTwo: [],
			pickerValueMulThreeThree: [],
			/* 是否显示控件 */
			showPicker: false
		};
	},
	props: {
		/* mode */
		mode: {
			type: String,
			default: 'selector'
		},
		/* picker 数值 */
		pickerValueArray: {
			type: Array,
			default() {
				return [];
			}
		},
		/* 默认值 */
		pickerValueDefault: {
			type: Array,
			default() {
				return [];
			}
		},
		/* 几级联动 */
		deepLength: {
			type: Number,
			default: 2
		}
	},
	watch: {
		mode(oldVal, newVal) {
			this.modeChange = true;
		},
		pickerValueArray(val) {
			this.initPicker(val);
		}
	},
	methods: {
		initPicker(valueArray) {


			let pickerValueArray = valueArray;
			this.pickerValue = this.pickerValueDefault;
			// 初始化多级联动
			if (this.mode === 'selector') {
				this.pickerValueSingleArray = valueArray;
			} else if (this.mode === 'timeSelector') {
				this.modeChange = false;
				let hourArray = [];
				let minuteArray = [];
				for (let i = 0; i < 24; i++) {
					hourArray.push({
						value: i,
						label: i > 9 ? `${i} 时` : `0${i} 时`
					});
				}
				for (let i = 0; i < 60; i++) {
					minuteArray.push({
						value: i,
						label: i > 9 ? `${i} 分` : `0${i} 分`
					});
				}
				this.pickerValueHour = hourArray;
				this.pickerValueMinute = minuteArray;
			} else if (this.mode === 'multiSelector') {
				this.pickerValueMulArray = valueArray;
			} else if (
				this.mode === 'multiLinkageSelector' &&
				this.deepLength === 2
			) {
				// 两级联动
				let pickerValueMulTwoOne = [];
				let pickerValueMulTwoTwo = [];
				// 第一列
				for (let i = 0, length = pickerValueArray.length; i < length; i++) {
					pickerValueMulTwoOne.push(pickerValueArray[i]);
				}
				// 渲染第二列
				// 如果有设定的默认值
				if (this.pickerValueDefault.length === 2) {
					let num = this.pickerValueDefault[0];
					for (
						let i = 0, length = pickerValueArray[num].children.length;
						i < length;
						i++
					) {
						pickerValueMulTwoTwo.push(pickerValueArray[num].children[i]);
					}
				} else {
					for (
						let i = 0, length = pickerValueArray[0].children.length;
						i < length;
						i++
					) {
						pickerValueMulTwoTwo.push(pickerValueArray[0].children[i]);
					}
				}
				this.pickerValueMulTwoOne = pickerValueMulTwoOne;
				this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
			} else if (
				this.mode === 'multiLinkageSelector' &&
				this.deepLength === 3
			) {
				let pickerValueMulThreeOne = [];
				let pickerValueMulThreeTwo = [];
				let pickerValueMulThreeThree = [];
				// 第一列
				for (let i = 0, length = pickerValueArray.length; i < length; i++) {
					pickerValueMulThreeOne.push(pickerValueArray[i]);
				}
				// 渲染第二列
				this.pickerValueDefault =
					this.pickerValueDefault.length === 3
						? this.pickerValueDefault
						: [0, 0, 0];
				if (this.pickerValueDefault.length === 3) {
					let num = this.pickerValueDefault[0];
					for (
						let i = 0, length = pickerValueArray[num].children.length;
						i < length;
						i++
					) {
						pickerValueMulThreeTwo.push(pickerValueArray[num].children[i]);
					}
					// 第三列
					let numSecond = this.pickerValueDefault[1];
					for (
						let i = 0,
							length =
								pickerValueArray[num].children[numSecond].children.length;
						i < length;
						i++
					) {
						pickerValueMulThreeThree.push(
							pickerValueArray[num].children[numSecond].children[i]
						);
					}
				}
				this.pickerValueMulThreeOne = pickerValueMulThreeOne;
				this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
				this.pickerValueMulThreeThree = pickerValueMulThreeThree;
			}
		},
		show() {
			setTimeout(() => {
				if (this.pickerValueArrayChange || this.modeChange) {
					this.initPicker(this.pickerValueArray);
					this.showPicker = true;
					this.pickerValueArrayChange = false;
					this.modeChange = false;
				} else {
					this.showPicker = true;
				}
			}, 0);
		},
		maskClick() {
			this.pickerCancel();
		},
		pickerCancel() {
			this.showPicker = false;
			this._initPickerVale();
			let pickObj = {
				index: this.pickerValue,
				value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
				label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
			};
			this.$emit('onCancel', pickObj);
		},
		pickerConfirm(e) {
			this.showPicker = false;
			this._initPickerVale();
			let pickObj = {
				index: this.pickerValue,
				value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
				label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
			};
			this.$emit('onConfirm', pickObj);
		},
		showPickerView() {
			this.showPicker = true;
		},
		pickerChange(e) {
			this.pickerValue = e.mp.detail.value;
			let pickObj = {
				index: this.pickerValue,
				value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
				label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
			};
			this.$emit('onChange', pickObj);
		},
		pickerChangeMul(e) {
			if (this.deepLength === 2) {
				let pickerValueArray = this.pickerValueArray;
				let changeValue = e.mp.detail.value;
				// 处理第一列滚动
				if (changeValue[0] !== this.pickerValue[0]) {
					let pickerValueMulTwoTwo = [];
					// 第一列滚动第二列数据更新
					for (
						let i = 0,
							length = pickerValueArray[changeValue[0]].children.length;
						i < length;
						i++
					) {
						pickerValueMulTwoTwo.push(
							pickerValueArray[changeValue[0]].children[i]
						);
					}
					this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
					// 第二列初始化为 0
					changeValue[1] = 0;
				}
				this.pickerValue = changeValue;
			} else if (this.deepLength === 3) {
				let pickerValueArray = this.pickerValueArray;
				let changeValue = e.mp.detail.value;
				let pickerValueMulThreeTwo = [];
				let pickerValueMulThreeThree = [];
				// 重新渲染第二列
				// 如果是第一列滚动
				if (changeValue[0] !== this.pickerValue[0]) {
					this.pickerValueMulThreeTwo = [];
					for (
						let i = 0,
							length = pickerValueArray[changeValue[0]].children.length;
						i < length;
						i++
					) {
						pickerValueMulThreeTwo.push(
							pickerValueArray[changeValue[0]].children[i]
						);
					}
					// 重新渲染第三列
					for (
						let i = 0,
							length =
								pickerValueArray[changeValue[0]].children[0].children.length;
						i < length;
						i++
					) {
						pickerValueMulThreeThree.push(
							pickerValueArray[changeValue[0]].children[0].children[i]
						);
					}
					changeValue[1] = 0;
					changeValue[2] = 0;
					this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
					this.pickerValueMulThreeThree = pickerValueMulThreeThree;
				} else if (changeValue[1] !== this.pickerValue[1]) {
					// 第二列滚动
					// 重新渲染第三列
					this.pickerValueMulThreeThree = [];
					pickerValueMulThreeTwo = this.pickerValueMulThreeTwo;
					for (
						let i = 0,
							length =
								pickerValueArray[changeValue[0]].children[changeValue[1]]
									.children.length;
						i < length;
						i++
					) {
						pickerValueMulThreeThree.push(
							pickerValueArray[changeValue[0]].children[changeValue[1]]
								.children[i]
						);
					}
					changeValue[2] = 0;
					this.pickerValueMulThreeThree = pickerValueMulThreeThree;
				}
				this.pickerValue = changeValue;
			}
			let pickObj = {
				index: this.pickerValue,
				value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
				label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
			};
			this.$emit('onChange', pickObj);
		},
		// 获取 pxikerLabel
		_getPickerLabelAndValue(value, mode) {
			let pickerLable;
			let pickerGetValue = [];
			// selector
			if (mode === 'selector') {
				pickerLable = this.pickerValueSingleArray[value].label;
				pickerGetValue.push(this.pickerValueSingleArray[value].value);
			} else if (mode === 'timeSelector') {
				pickerLable = `${this.pickerValueHour[value[0]].label}-${
					this.pickerValueMinute[value[1]].label
				}`;
				pickerGetValue.push(this.pickerValueHour[value[0]].value);
				pickerGetValue.push(this.pickerValueHour[value[1]].value);
			} else if (mode === 'multiSelector') {
				for (let i = 0; i < value.length; i++) {
					if (i > 0) {
						pickerLable +=
							this.pickerValueMulArray[i][value[i]].label +
							(i === value.length - 1 ? '' : '-');
					} else {
						pickerLable = this.pickerValueMulArray[i][value[i]].label + '-';
					}
					pickerGetValue.push(this.pickerValueMulArray[i][value[i]].value);
				}
			} else if (mode === 'multiLinkageSelector') {
				/* eslint-disable indent */
				pickerLable =
					this.deepLength === 2
						? `${this.pickerValueMulTwoOne[value[0]].label}-${this.pickerValueMulTwoTwo[value[1]].label}`
						: `${this.pickerValueMulThreeOne[value[0]].label}-${this.pickerValueMulThreeTwo[value[1]].label}-${this.pickerValueMulThreeThree[value[2]].label}`;
				if (this.deepLength === 2) {
					pickerGetValue.push(this.pickerValueMulTwoOne[value[0]].value);
					pickerGetValue.push(this.pickerValueMulTwoTwo[value[1]].value);
				} else {
					pickerGetValue.push(this.pickerValueMulThreeOne[value[0]].value);
					pickerGetValue.push(this.pickerValueMulThreeTwo[value[1]].value);
					pickerGetValue.push(this.pickerValueMulThreeThree[value[2]].value);
				}
				/* eslint-enable indent */
			}
			return {
				label: pickerLable,
				value: pickerGetValue
			};
		},
		// 初始化 pickerValue 默认值
		_initPickerVale() {
			if (this.pickerValue.length === 0) {
				if (this.mode === 'selector') {
					this.pickerValue = [0];
				} else if (this.mode === 'multiSelector') {
					this.pickerValue = new Int8Array(this.pickerValueArray.length);
				} else if (
					this.mode === 'multiLinkageSelector' &&
					this.deepLength === 2
				) {
					this.pickerValue = [0, 0];
				} else if (
					this.mode === 'multiLinkageSelector' &&
					this.deepLength === 3
				) {
					this.pickerValue = [0, 0, 0];
				}
			}
		}
	}
};
</script>

<style>
.pickerMask {
	position: fixed;
	z-index: 1000;
	top: 0;
	right: 0;
	left: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.6);
}

.mpvue-picker-content {
	position: fixed;
	bottom: 0;
	left: 0;
	width: 100%;
	transition: all 0.3s ease;
	transform: translateY(100%);
	z-index: 3000;
}

.mpvue-picker-view-show {
	transform: translateY(0);
}

.mpvue-picker__hd {
	display: flex;
	padding: 9px 15px;
	background-color: #fff;
	position: relative;
	text-align: center;
	font-size: 17px;
}

.mpvue-picker__hd:after {
	content: ' ';
	position: absolute;
	left: 0;
	bottom: 0;
	right: 0;
	height: 1px;
	border-bottom: 1px solid #e5e5e5;
	color: #e5e5e5;
	transform-origin: 0 100%;
	transform: scaleY(0.5);
}

.mpvue-picker__action {
	display: block;
	flex: 1;
	color: #1aad19;
}

.mpvue-picker__action:first-child {
	text-align: left;
	color: #888;
}

.mpvue-picker__action:last-child {
	text-align: right;
}

.picker-item {
	text-align: center;
	line-height: 40px;
	font-size: 16px;
}

.mpvue-picker-view {
	position: relative;
	bottom: 0;
	left: 0;
	width: 100%;
	height: 238px;
	background-color: rgba(255, 255, 255, 1);
}
</style>
