<template>
	<view :show="show && !disabled" mode="bottom" :round="round">
		<view class="time-content">
			<view class="header-top">
				<slot name="header">
					<view class="cancel" @click="cancel">{{cancelText}}</view>
					<view class="title">{{title}}</view>
					<view class="confirm" @click="confirm">{{confirmText}}</view>
				</slot>
			</view>
			<view class="time-wrapper">
				<picker-view
					:value="pickerValue" 
					indicator-class="picker-box"
					:indicator-style="indicatorStyle"
					@change="bindChange"
				>
					<picker-view-column v-for="(item,index) in innerColumns" :key="index">
					    <view class="item" v-for="(item1,index1) in item.values" :key="index1">
							{{item1}}{{item.label}}
						</view>
					</picker-view-column>
				</picker-view>
			</view>
		</view>
	</view>
</template>
<script>
	export default {
		name: 'GDatepicker',
		/**
		 * 插槽
		 * header  自定义头部样式
		 */
		props:{
			value:{
				type: [String,Number],
				default:''
			},
			show: {
				type:[Boolean,String],
				default:false
			},
			cancelText: {
				type:String,
				default:'取消'
			},
			confirmText: {
				type:String,
				default:'确定'
			},
			title: {
				type:String,
				default:'时间选择'
			},
			/**
			 * 是否格式化时间
			 * format 格式同 uView timeFormat API，如："yyyy-mm-dd"
			 * 格式可以自由搭配: 年为"yyyy"，月为"mm"，日为"dd"，时为"hh"，分为"MM"，秒为"ss"，
			 * 注意分为 大写M
			  */
			format: {
				type:String,
				default:''
			},
			// 是否转换成json格式数据 如：2020-01-01T19:19:20.253Z
			formatToJson: {
				type: Boolean,
				default: false
			},
			/**
			 * 时间模式（选择器可选时间格式）(如果mode为date,则format不应包含时分秒格式)
			 * datetime  全时间：年月日时分秒
			 * date  只包含年月日
			 */
			mode: {
				type: String,
				default: 'datetime'
			},
			// 可选的最大时间 时间戳毫秒 默认后十年
			maxDate: {
				type: [String, Number],
				default: new Date(new Date().getFullYear() + 10, 0, 1).getTime(),
			},
			// 可选的最小时间 时间戳毫秒 默认前十年
			minDate: {
				type: [String, Number],
				default: new Date(new Date().getFullYear() - 10, 0, 1).getTime(),
			},
			minMonth: {
				type: [String, Number],
				default: 1
			},
			maxMonth: {
				type: [String, Number],
				default: 12
			},
			minDay: {
				type: [String, Number],
				default: 1
			},
			maxDay: {
				type: [String, Number],
				default: 31
			},
			// 弹窗圆角值
			round: {
				type: [String, Number],
				default:0
			},
			disabled:{
				type:Boolean,
				default:false
			}
		},
        model: {
			prop: 'value',
			event: 'input'
		},
		data() {
			return {
				year: 2022,
				month: 0,
				day: 0,
				hour: 0,
				minute: 0,
				second: 0,
				pickerValue: [], // picker-view绑定值
				innerColumns: [],
				indicatorStyle: `color: red;!important`
			}
		},
		watch:{
			show(val) { 
				if(val) {
                    this.initData()
					if(this.value) {
						this.setData(this.value)
					} else {
						this.setData()
					}
				}
			}
		},
		// mounted() {
			// this.initData()
		// },
		methods: {
			initData() {
				const startYear = new Date(Number(this.minDate)).getFullYear()
				const endYear = new Date(Number(this.maxDate)).getFullYear()
				let result = [
					{
						type: 'year',
						label: '年',
						range: [startYear, endYear]
					},
					{
						type: 'month',
						label: '月',
						range: [this.minMonth, this.maxMonth]
					},
					{
						type: 'day',
						label: '日',
						range: [this.minDay, this.maxDay]
					},
					{
						type: 'hour',
						label: '时',
						range: [0,23]
					},
					{
						type: 'minute',
						label: '分',
						range: [0, 59]
					},
					{
						type: 'secode',
						label: '秒',
						range: [0, 59]
					}
				]
				this.innerColumns = result.map(({ type, label, range }) => {
					const num = range[1] - range[0] + 1;
					let values = this.getColumnTimes(num, (index) => {
					    let value = range[0] + index
					    value = type === 'year' ? `${value}` : this.padZero(value)
					    return value
					})
					return { type, label, values }
				})
				if(this.mode === "date") {
					this.innerColumns.splice(3,3)
				}
			},
			bindChange (e) {
			    const val = e.detail.value;
				const date = new Date();
				this.year = this.getCurrCol(0)[val[0]] || date.getFullYear()
				this.month = this.getCurrCol(1)[val[1]] ||date.getMonth() + 1;
				this.day = this.getCurrCol(2)[val[2]] || date.getDate()
				this.hour = this.getCurrCol(3)[val[3]] || date.getHours();
				this.minute = this.getCurrCol(4)[val[4]] || date.getMinutes();
				this.second = this.getCurrCol(5)[val[5]] || date.getSeconds();
				/* // change事件 需要启用取消注释
				const currentTime = new Date(this.year,this.month - 1,this.day,this.hour,this.minute,this.second).getTime()
				if(this.format) {
					this.$emit('change',uni.$u.timeFormat(currentTime,this.format))
				} else {
					this.$emit('change',currentTime)
				} */
			},
			getCurrCol(index) {
				if(!this.innerColumns[index]) {
					return []
				}
				return this.innerColumns[index].values
			},
			cancel() {
				this.$emit('cancel')
				this.$emit('update:show',false)
			},
			confirm() {
				const str = `${this.year}/${this.month}/${this.day} ${this.hour}:${this.minute}:${this.second}`
				const time = new Date(str).getTime()
				this.$emit('confirm',this.formatDate(time))
                this.$emit('input', this.formatDate(time));
			},
			// set data
			setData(value) {
				let date;
				if(value) {
					const n = isNaN(value) ? value : Number(value)
					date = new Date(n)
				} else {
					date = new Date()
				}
				const startYear = new Date(Number(this.minDate)).getFullYear()
				this.year = date.getFullYear()
				// 绑定时间小于当前时间列表的开始时间则取第一项
				const yearColumnIndex = this.year > startYear ? this.year - startYear : 0
				this.day = date.getDate()
				this.month = date.getMonth() + 1
				this.hour = date.getHours()
				this.minute = date.getMinutes()
				this.second = date.getSeconds()
				// pickerValue数组中的项依次表示 picker-view 内的 picker-view-column 选择的第几项
				this.pickerValue = [yearColumnIndex,this.month - 1,this.day - 1,this.hour,this.minute,this.second]
				this.$nextTick(() => {
					if(this.mode === "date") {
						this.pickerValue.splice(3,3)
					}
				})
			},
			formatDate(time) {
				if(this.format) {
					return uni.$u.timeFormat(time,this.format)
				} else if(this.formatToJson) {
					return new Date(time).toJSON()
				} else {
					return time
				}
			},
			// 设置列数据
			getColumnTimes(n, iteratee) {
			    let index = -1
			    const result = Array(n < 0 ? 0 : n)
			    while (++index < n) {
			        result[index] = iteratee(index)
			    }
			    return result
			},
			// 字符串转换
			padZero(num, targetLength = 2) {
			    let str = `${num}`
			    while (str.length < targetLength) {
			        str = `0${str}`
			    }
			    return str
			}
		}
	}
</script>
<style lang="scss" scoped>
	picker-view {
	  width: 100%;
		height: 100%;
	}
	
	.time-content {
		height: 280px;
		.header-top {
			height: 44px;
			line-height: 44px;
			display: flex;
			padding: 0 16px;
			font-size: 15px;
			border-bottom: 1px solid #EEEEEE;
			overflow: hidden;
			.cancel {
				color: #999999;
			}
			.title {
				flex: 1;
				text-align: center;
				color: #666666;
			}
			.confirm {
				color: #27B57D;
			}
		}
		.time-wrapper {
			height: calc(100% - 44px);
			box-sizing: border-box;
			text-align: center;
			.picker-box {
				height: 44px;
				font-size: 18px!important;
				font-weight: 800!important;
				color: #333333!important;
			}
			.item {
			    line-height: 44px;
			    text-align: center;
			}
		}
	}
</style>