<template>
	<view class="calendar-content" v-if="show">
		<view @click="close" style="height: 100%;"></view>
		<view class="calendar-body">
			<view class="calendar-header">
				<view :class="{
					'not-clear': pickerArray[0] == null,
					'clear': pickerArray[0] !=null,
				}" @click="clear">清除</view>
				<view class="title">
					<text v-if="pickerArray.length==0">选择日期</text>
					<text v-else-if="pickerArray.length==1 && multi == false">{{pickerArray[0].slice(5).replace('/','月')+ '日'}}</text>
					<view class="date-range" v-else>
						<!-- <view v-show="pickerArray[0]==null" style="color: #8F8F94;">开始日期</view> -->
						<text v-show="pickerArray[0]!=null">{{pickerArray[0].slice(5).replace('/','月')+ '日'}}</text>
						<text>-</text>
						<view v-show="pickerArray[1]==null" style="color: #8F8F94;">结束日期</view>
						<text v-if="pickerArray[1]!=null">{{pickerArray[1].slice(5).replace('/','月')+ '日'}}</text>
					</view>
				</view>
				<view
				:class="{
					'not-confirm': true,
					'confirm': (pickerArray[0] != null && multi == false)|| (pickerArray[1] != null && multi == true)
				}"
				@click="save"
				>保存</view>
			</view>
			<view class="calendar-picker">
				<view class="calendar-week">
					<view v-for="(v, i) in weekArray" :key="i" class="week">
						{{v}}
					</view>
				</view>
				
				<scroll-view
					:scroll-y="true"
					class="calendar-scroll"
				>
					<block v-for="(v, i) in calendarEmptyTempArray" :key="i">
						<view class="monthAndyear">{{v[3]}}年{{v[2]}}月</view>
						<view class="calendar-days-content">
							<view class="calendar-empty-day" v-for="(e) in v[0]" :key="e.id"></view>
							<view class="calendar-day-content" v-for="(d, i) in v[4]" :key="i" @click="picker([v[3], v[2], i+1])">
								<view  :class="{
									'calendar-day': true,
									'calendar-disable-day': `${v[3]}/${prefixZero(v[2])}/${prefixZero(i+1)}`< today,
									'calendar-today': `${v[3]}/${prefixZero(v[2])}/${prefixZero(i+1)}` == today,
									'calendar-picker-start':  `${v[3]}/${prefixZero(v[2])}/${prefixZero(i+1)}` == pickerArray[0] && pickerArray.length > 1,
									'calendar-picker-day': `${v[3]}/${prefixZero(v[2])}/${prefixZero(i+1)}` > pickerArray[0] && `${v[3]}/${prefixZero(v[2])}/${prefixZero(i+1)}` < pickerArray[1],
									'calendar-picker-end': `${v[3]}/${prefixZero(v[2])}/${prefixZero(i+1)}` == pickerArray[1],
									'calnedar-picker-single': `${v[3]}/${prefixZero(v[2])}/${prefixZero(i+1)}` == pickerArray[0] && pickerArray.length == 1
								}" >
								{{i+1}}
								</view>
							</view>
							
						</view>
					</block>
				</scroll-view>
				
			</view>
		</view>
	</view>
</template>

<script>
/*
* @description 组件可以对日期进行单选，多选，使用酒店预定、飞机票火车票预定
* @__author__:Sorry_hx, __email__:1317205072@qq.com
* @property {String} starDate 单选为选中日期，多选为选中开始日期，默认选择为今天，需要autoChoose = true, YYYY/MM/DD
* @property {String} endDate 单选无效，多选为选中结束日期，默认选择为明天， 需要autoChoose = true, YYYY/MM/DD
* @property {Boolean} multi 多选模式
* @property {Boolean} autoChoose 自动选择输入日期，默认为false
* @property {Boolean} autoClear 保存自动清除选择，默认为true
* @property {Number} range 日历月份数，自本月起的往后几个月的日历，默认为13个月，即明年的本月
* @event {Array} change 触发change时间，返回日期数组
*/
export default{
	props:{
		startDate:{
			type: String,
			default: ''
		},
		endDate:{
			type: String,
			default: ''
		},
		multi:{
			type: Boolean,
			default: true
		},
		autoChoose:{
			type: Boolean,
			default: false
		},
		autoClear:{
			type: Boolean,
			default: true
		},
		range: {
			type: Number,
			default: 13
		},  // 默认显示至下年本月日历,
	},
	data(){
		return{
			weekArray: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
			monthDaysArray: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
			year: 1970,
			month: 1,
			date: 1,
			weekDay: 0,
			calendarEmptyTempArray: [] ,// [月份第一天索引，月份最后一天临时变量, 月份，年份.当月天数]
			pickerArray:[], // 选择日期的开始与结束
			pickerStartDate:'',
			pickerEndDate:'',
			today: '',
			rangeArray: [],
			pickerStamp: 0,
			show: false
		}
	},
	computed:{
	},
	methods:{
		getCalendar(){
			const date = new Date()
			this.year = date.getFullYear()
			this.updateFebruarydays(this.year)
			this.month = date.getMonth() + 1
			this.date = date.getDate()
			this.weekDay = date.getDay()
			this.today = this.getDate(date)
			const tomorrowDate = this.getDate(new Date(date.getTime() + 24*60*60*1000))
			
			if (this.multi  && this.autoChoose){
				if (this.startDate != '' && this.endDate != '' && this.startDate < this.endDate && this.startDate.replace(/-/g, '/') >= this.today){
					this.pickerArray=[this.startDate.replace(/-/g, '/'), this.endDate.replace(/-/g, '/')]
				}else{
					this.pickerArray=[this.today, tomorrowDate]
				}
			}else if(!this.multi && this.autoChoose){
				if (this.startDate != '' && this.startDate.replace(/-/g, '/') >= this.today){
					this.pickerArray=[this.startDate.replace(/-/g, '/')]
					
				}else{
					this.pickerArray=[this.today]
					
				}
				
			}
			const firstDay = new Date(`${this.year}-${this.month}-01`).getDay() //获取本月第一天
			// 获取接下来月份的数组，用于渲染日历 [月份第一天索引，月份最后一天临时变量, 月份，年份.当月天数]
			let month // 临时月份
			let year = this.year
			for (let i=0; i<this.range; i++){
				if(i > 0){
					let preDay = (this.calendarEmptyTempArray[i-1][1]+1)%7
					month = month + 1
					if(month > 12){
						year ++
						month = month - 12 
						this.updateFebruarydays(year)
					}
					let monthDays = this.monthDaysArray[month-1]
					let laterDay = (preDay + monthDays)%7 - 1
					this.calendarEmptyTempArray[i] = [preDay, laterDay, month, year, monthDays]
				}else{
					month = this.month
					let monthDays = this.monthDaysArray[month-1]
					let laterDay = (firstDay + monthDays)%7 - 1
					this.calendarEmptyTempArray[0] = [firstDay, laterDay, month, year, monthDays]
				}
			}
			
		},
		getDate(date){
			return `${date.getFullYear()}/${this.prefixZero(date.getMonth() + 1)}/${this.prefixZero(date.getDate())}`
		},
		updateFebruarydays(year){
			// 初步估计侦听器只会在组件的onshow生命周期侦听最初与最终的值，改动函数手动更新，后续慢慢研究
			if(year%4==0&&year%100!=0||year%400==0){
				this.monthDaysArray[1] = 29
			}else{
				this.monthDaysArray[1] = 28
			}
		},
		getDayClass(date, month, year){
			// 计算样式
			if (date<this.date && month == this.month && year == this.year){
				return 'calendar-disable-day'
			}else if(date == this.date && month == this.month && year == this.year){
				return 'calendar-today'
			}
			return 'calendar-day'
		},
		prefixZero(num){
			// 补零,标准化
			if (num>10){
				return num
			}else{
				return (Array(2).join(0) + num).slice(-2)
			}
		},
		getTomorrowDate(todayDate, month){
			const d = todayDate + 1
			// if (d>)
		},
		dateScope(startDateStr, endDateStr){
			const startTime = new Date(startDateStr).getTime()
			const endTime = new Date(endDateStr).getTime()
			const oneDay = 24*60*60*1000
			let l = []
			let i
			for (i=startTime; i<=endTime;){
				l.push(this.getDate(new Date(i)).replace(/\//g, '-'))
				i += oneDay
			}
			return l
		},
		picker(dateArray){
			let [year, month, day] = dateArray
			let date = `${year}/${this.prefixZero(month)}/${this.prefixZero(day)}`
			if (date < this.today){
				// 禁止前面日期点击
				return null
			}
			if (this.multi == true){
				if (this.pickerStamp == 0){
					this.pickerArray = [date]
					this.pickerStamp = 1
				}else{
					if (date>this.pickerArray[0]){
					
						this.pickerArray.push(date)
						this.pickerStamp = 0
					}else{
						// 实现日期小于第一次选择时变为重选
						this.pickerArray = [date]
						this.pickerStamp = 1
					}
				}
			}else{
				this.pickerArray = [date]
			}
		},
		clear(){
			// 清除日期选择
			this.pickerArray = []
		},
		save(e){
			if (this.multi == true){
				if (this.pickerArray.length == 2){
					this.$emit('change', this.dateScope(this.pickerArray[0], this.pickerArray[1]))
					this.show = false
					if (this.autoClear){
						this.clear()
					}
				}
			}else{
				this.$emit('change', [this.pickerArray[0].replace(/\//g, '-')])
				this.show = false
				if (this.autoClear){
					this.clear()
				}
			}
			
		},
		close(){
			this.show = false
		},
		open(){
			this.show = true
		}
	},
	onShow:function() {
		this.getCalendar()
	}
}
</script>

<style lang="scss" scoped>
@mixin border-bottom {
	border-bottom-color: #d4d4d4;
	border-bottom-style: solid;
	border-bottom-width: thin;
}
.calendar-content{
	position: fixed;
	top: 0;
	width: 100%;
	height: 100%;
	background-color: rgba($color: #000000, $alpha: 0.5);
	left: 0;
	z-index: 99;
	.calendar-body{
		height: 800rpx;
		width: 100%;
		background-color: #FFFFFF;
		position: fixed;
		bottom: 0;
		.calendar-header{
			@include border-bottom;
			height: 100rpx;
			display: flex;
			justify-content: space-between;
			padding: 0 40rpx;
			align-items: center;
			
			.clear{
				color: $uni-color-primary;
			}
			.not-clear{
				color: rgba($color: $uni-color-primary, $alpha: 0.5);
			}
			.confirm{
				color: $uni-color-primary !important;
			}
			.not-confirm{
				color: rgba($color: $uni-color-primary, $alpha: 0.5);
			}
			.title{
				font-size: 32rpx;
				.date-range{
					display: flex;
					width: 300rpx;
					justify-content: space-between;
				}
			}
		}
		.calendar-picker{
			display: flex;
			flex-direction: column;
			align-items: center;
			.calendar-week{
				display: flex;
				justify-content: flex-start;
				height: 70rpx;
				align-items: center;
				width: 700rpx;
				@include border-bottom;
				.week{
					width: 100rpx;
					text-align: center;
					font-size: 30rpx;
				}
				
			}
			.calendar-scroll{
				width: 700rpx;
				height: 610rpx;
				.monthAndyear{
					font-size: 32rpx;
					padding-left: 34rpx;
					height: 60rpx;
					display: flex;
					align-items: flex-end;
					
				}
				.calendar-days-content{
					display: flex;
					justify-content: flex-start;
					flex-wrap: wrap;
					width: 700rpx;
					@include border-bottom;
					.calendar-empty-day{
						width: 100rpx;
						height: 100rpx;
					}
					.calendar-day-content{
						height: 110rpx;
						width: 100rpx;
						display: flex;
						align-items: center;
						justify-content: center;
						.calendar-day{
							width: 100rpx;
							height: 100rpx;
							text-align: center;
							line-height: 100rpx;
							font-size: 30rpx;
						}
						.calendar-today{
							// @extend .calendar-day;
							border-radius: 50%;
							border-style: solid;
							border-width: thin;
							border-color: #d4d4d4;
							box-sizing: border-box;
						}
						.calendar-disable-day{
							// @extend .calendar-day;
							color: #d4d4d4;
						}
						.calendar-picker-start{
							border-top-left-radius: 50%;
							border-bottom-left-radius: 50%;
							border-top-right-radius: 0;
							border-bottom-right-radius: 0;
							background-color: $uni-color-primary;
							border-color: $uni-color-primary;
							color: #FFFFFF;
							// box-sizing: inherit !important;
						}
						.calendar-picker-day{
							background-color: $uni-color-primary;
							border-color: $uni-color-primary;
							color: #FFFFFF;
						}
						.calendar-picker-end{
							border-top-left-radius: 0;
							border-bottom-left-radius: 0;
							border-top-right-radius: 50%;
							border-bottom-right-radius: 50%;
							background-color: $uni-color-primary;
							color: #FFFFFF;
							border-color: $uni-color-primary;
						}
						.calnedar-picker-single{
							border-radius: 50%;
							border-color: $uni-color-primary;
							background-color: $uni-color-primary;
							color: #FFFFFF;
						}
					}
					
				}
			}
		}
	}
}
</style>
