<template>
	<div class="container">
		<div class="week-wrap">
			<label :style="{'width':labelwidth+'px'}" class="cell-label" v-if="label">{{label}}</label>
			<div class="cell-body" :style="{'border-color':borderColor}" @click="selectWeek">
				<span>{{showYearWeek.yearWeek}}</span>
				<input style="display: none;" type="text" v-model="inputValue" :readonly="readonly" :disabled="disabled" :placeholder="placeholder"/>
				<img :class="{'transition':showWeek}" class="arrow-icon" src="../assets/imgs/arrow-icon.png" alt="">
			</div>
		</div>
		<!-- 弹出周选择器 -->
		<van-popup
			v-model="showWeek"
			position="bottom">
			<div class="calendar-wrap">
				<div class="calendar-header">
					<van-icon name="arrow-left" @click="preMonth" />
					<span>{{yearMonth}}</span>
					<van-icon name="arrow" @click="nextMonth"/>
				</div>
				<div class="week-line">
					<span class="week" v-for="item in week" :key="item">{{item}}</span>
				</div>
				<div class="day-table">
					<div class="day-line" v-for="(item,index) in calendayDayList" :key="index" @click="weekPick(item[0])" :class="{'active':showYearWeek.yearWeek==item[0].week.yearWeek}">
						<span class="day" v-for="(items,dayindex) in item" :key="dayindex" :class="items.class">{{items.day}}</span>
					</div>
				</div>
			</div>
		</van-popup>
	</div>
</template>

<script>
export default{
	model:{
		prop: 'value',
		event: 'change'
	},
	props:{
		value:{
			type:String,
			default:''
		},
		label:{
			type:String,
			default:''
		},
		placeholder:{
			type:String,
			default:''
		},
		readonly:{
			type:Boolean,
			default:true
		},
		disabled:{
			type:Boolean,
			default:false
		},
		labelwidth:{
			type:[String,Number],
			default:'60'
		},
		borderColor:{
			type:String,
			default:'#6992dd'
		}
	},
	data(){
		return{
			inputValue:this.value,
			showWeek:false,
			yearMonth:'',//显示头部年月
			week:['一','二','三','四','五','六','日'],
			today:new Date(),//当前时间
			year:new Date().getFullYear(),//当前年份
			month:new Date().getMonth()+1,//当前月份
			day:new Date().getDate(),//当前日
			allday:0,//月总天数
			calendayDayList:[]
		}
	},
	created() {
		
		
	},
	mounted() {
		//初始化周选择器
		this.getCalendayAllDay();
	},
	methods:{
		//显示周选择器
		selectWeek(){
			if(!this.disabled){
				this.showWeek = !this.showWeek;
				if(this.value){					
					this.today = new Date(this.value);//当前时间
					this.year = new Date(this.value).getFullYear();//当前年份
					this.month = new Date(this.value).getMonth()+1;//当前月份
					this.day = new Date(this.value).getDate();//当前日
				}else{
					this.today = new Date();//当前时间
					this.year = new Date().getFullYear();//当前年份
					this.month = new Date().getMonth()+1;//当前月份
					this.day = new Date().getDate();//当前日
				}		
				this.getCalendayAllDay();
			}			
		},
		//显示年月
		showYearMonth(){
			if(this.month<10){	//给小于10的数字前面加0
				this.yearMonth = this.year +" 年 "+"0"+ this.month +" 月 ";
			}else{
				this.yearMonth = this.year +" 年 "+ this.month +" 月 ";
			}
		},
		//计算某月总天数
		countDay(month){
			let allday = 0;
			let year = this.year; 
			if(month!=2){
				if(month==4 || month==6 || month==9 || month==11)//判断月是30天还是31天,2月除外
					allday = 30;
				else
					allday = 31;
			}else{
				if((year%4==0 && year%100!=0) || (year%400==0))//判断是否是闰年，进行相应的改变
					allday = 29;
				else
					allday = 28;
			}
			return allday;
		},
		//获取显示日历的天数
		getCalendayAllDay(){
			//获取当前月的总天数
			let allday = this.allday = this.countDay(this.month);
			let year = this.year;
			let month = this.month;
			
			let fistdate = new Date(year,month-1,0); 
			let xinqi = fistdate.getDay(); //获取一天是星期几
			let lastxinqi = new Date(year,month-1,allday).getDay();//获取最后一天是星期几
			let preMday = this.countDay(month-1);//上一个月的总天数
			let nextDayCount = 1;//下一个月的第一天
			let dayList = [];//日历日期集合
			
			//上月的最后几天的日期
			for(let i=0;i<xinqi;i++){	
				let obj = {
					day:preMday,
					class:'pre-day',
					week:this.getYearWeek(this.year,this.month-1,preMday)
				}
				dayList.unshift(obj)
				preMday--;
			}
			//当前月的所有日期
			for(let j=1;j<=allday;j++){	
				let obj = {};
				if(j<10){		//给小于10的数字前面加0
					obj = {
						day:"0"+j,
						class:'now-day',
						week:this.getYearWeek(this.year,this.month,j)
					}
					dayList.push(obj)
				}else{
					obj = {
						day:j,
						class:'now-day',
						week:this.getYearWeek(this.year,this.month,j)
					}
					dayList.push(obj)
				}
			}
			//下个月的前几天显示天数
			for(let i=lastxinqi;i<7;i++){		
				if(nextDayCount<10){		//给小于10的数字前面加0		
					let obj = {
						day:"0"+nextDayCount,
						class:'next-day',
						week:this.getYearWeek(this.year,this.month+1,nextDayCount)
					};
					dayList.push(obj)
				}
				nextDayCount++;			  
			}
			this.calendayDayList = _.chunk(dayList,7);
			this.showYearMonth();
		},
		//上一月
		preMonth(){
			if(this.month>1){
				this.month = this.month-1;
			}else{
				this.month = 12;
				this.year = this.year-1;
			}
			this.getCalendayAllDay();
		},
		// 下一月
		nextMonth(){
			if(this.month<12){
				this.month = this.month+1;
			}else{
				this.month = 1;
				this.year = this.year+1;
			}
			this.getCalendayAllDay();
		},	
		//根据当前日期获取某一周的周一（第一天）
		getFirstDayOfWeek(date){
			let day = date.getDay() || 7;
			let date2 = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1 - day);
			let m = date2.getMonth()+1 >= 10 ? date2.getMonth()+1 : '0'+(date2.getMonth()+1);
			let d = date2.getDate() >= 10 ? date2.getDate() : '0'+date2.getDate();
			return date2.getFullYear()+'-'+m+'-'+d;
		},
		getYearWeek(y,m,d){
			/*  
				date1是当前日期  
				date2是当年第一天  
				day是当前日期是今年第多少天  
				用day + 当前年的第一天的周差距的和在除以7就是本年第几周  
				week是当前周
				weekFirstDate是这一周的第一天
			*/		
			let date1 = new Date(y, parseInt(m) - 1, d),
					date2 = new Date(y, 0, 1),
					day = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
			let week = Math.ceil((day + ((date2.getDay() + 1) - 1)) / 7);
			let weekFirstDay = this.getFirstDayOfWeek(new Date(y+'-'+m+'-'+d))
			let obj = {
				week:week,
				yearWeek:y+'第'+week+'周',
				weekFirstDate:weekFirstDay,
			}
			return obj;
		},
		//选择周
		weekPick(item){
			this.inputValue = item.week.weekFirstDate;
			this.showWeek = false;
		},
	},
	computed:{
		showYearWeek(){
			let date = '';
			if(this.inputValue){
				date = new Date(this.inputValue);
			}else{
				date = new Date();
			}		
			let y = date.getFullYear();
			let m = date.getMonth();
			let d = date.getDate();		
			return this.getYearWeek(y,m+1,d)
		}
	},
	watch:{
		value(value){
			this.inputValue = value;
		},
		inputValue(value){
			this.$emit("change", value)
		}
	}
}
</script>

<style scoped lang="scss">
	.week-wrap{
		line-height:35px;
		display: flex;
		padding: 5px 16px;
		font-size: 14px;
		.cell-label{
			color: #646566;
			margin-right: 12px;
		}
		.cell-body{
			border-width: 1px;
			border-style: solid;
			flex: 1;
			box-sizing: border-box;
			padding: 0 30px;
			position: relative;
			font-size: 14px;
			&::before{
				content: "";
				height: 12px;
				width: 14px;
				background: url(../assets/imgs/calander-icon.png) no-repeat;
				background-size: 100% 100%;
				position: absolute;
				top: 50%;
				left: 15px;
				transform: translate(-50%,-50%);
			}
			input{
				padding: 0;
				margin: 0;
				border: none;
				width: 100%;
			}
			.arrow-icon{
				position: absolute;
				height: 9px;
				top: 50%;
				right: 3px;
				transition: all .5s;
				transform: translate(-50%,-50%);
				&.transition{
					transform: translate(-50%,-50%) rotate(-180deg);
				}
			}
		}
	}
	.calendar-wrap{
		padding: 10px 20px 20px;
		.calendar-header{
			text-align: center;
			height: 40px;
			line-height: 40px;
			font-size: 16px;
			span{
				margin: 0 25px;
			}
			.van-icon{
				padding: 10px;
			}
		}
		.week-line{
			display: flex;
			text-align: center;
			border-bottom: 1px solid #f1f1f1;
			.week{
				flex: 1;
				height: 35px;
				line-height: 35px;
				font-size: 14px;
			}
		}
		.day-table{
			padding-top: 5px;
			.day-line{
				display: flex;
				text-align: center;
				&.active{
					background: #F2F5FC;
					border-radius: 12px;
				}
				.day{
					flex: 1;
					height: 35px;
					line-height: 35px;
					font-size: 14px;
					&.pre-day{
						color: #c0c4cc;
					}
					&.next-day{
						color: #c0c4cc;
					}
				}
			}
		}
	}
</style>
