<template>
    <div class="calendar">
        <div class="c__hd">
            <div class="c__date" @click="onToggleType">{{ curDays.year }}年<span>{{ curDays.month.toString().length >= 2 ? curDays.month : '0' + curDays.month }}月</span></div>
            <div class="c__change" v-if="calendarType !== 'small'">
                <!-- <van-icon  name="arrow-left" />
                <van-icon name="arrow" /> -->
                <img :src="imgs.arrow1" alt="" @touchstart.stop.prevent="slidePrev"  @touchend.stop.prevent="endTouch" class="arrow arrow-left">
                 <img :src="imgs.arrow2" alt=""  @touchstart.stop.prevent="slideNext" @touchend.stop.prevent="endTouch" class="arrow">
            </div>
        </div>
        <div class="week-title">
            <span>一</span>
            <span>二</span>
            <span>三</span>
            <span>四</span>
            <span>五</span>
            <span>六</span>
            <span>日</span>
        </div>

        <swiper :options="swiperOption" ref="mySwiper" @slideChangeTransitionEnd="slideChangeTransitionEnd" style="height: auto">
            <swiper-slide v-for="(day, current) in daySet" :key="current">
                <div class="tr">
                    <template v-for="(i, index) in day">
                        <div :key="index" :class="[calendarType == 'small' ? 'small' : '', 'td']">
                            <span @click.stop="onSelectDay(i)"
                            :class="[i.disabled ? 'disabled' : '',
                                    i.noCheck? 'noCheck' : '',
                                    i.toDay ? 'today' : '',
                                    i.nowDate == selectElement ? 'active' : '']">{{ i.dayNum }}</span>
                        </div>
                    </template>
                </div>
            </swiper-slide>
        </swiper>
    </div>
</template>
<script>
import 'swiper/dist/css/swiper.css'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import dayjs from 'dayjs'
export default {
    name: 'calendar',
    components: { swiper, swiperSlide },
    props: {
        dataList: {
            type: Array,
            default() {
                return []
            }
        },
        dayList: { // 当月哪天有数据
            type: Array,
            default() {
                return []
            }
        },
        type: {
            type: String,
            default: 'default' // small 一排日历
        }
    },
    data() {
        return {
            calendarType: this.type, // 日历类型
            dayDateList: [],
            swiperOption: {
                autoHeight: true,
                initialSlide: 13,
                // loop:false,
                // mode: 'horizontal',
                // freeMode:false,
                // touchRatio:0.5,
                // longSwipesRatio:0.1,
                // threshold:50,
                // followFinger:false,
                centeredSlides: true,
                observer: true,//修改swiper自己或子元素时，自动初始化swiper
                observeParents: true,//修改swiper的父元素时，自动初始化swiper
                // effect : 'coverflow',
            },
            OS: Object.prototype.toString,
            // 一周的第一天
            // 0表示周日，依次类推
            startWeek: 1,
            daySet: [], // 月数据
            curDays: {
                year: new Date().getFullYear(),
                month: new Date().getMonth() + 1
            },
            points: { // 手势移动位置
                startX: 0,
                startY: 0,
                endX: 0,
                endY: 0
            },
            selectElement: null, // 选中的元素 根据日期来判断是否一致
            imgs:{
                arrow1:require('@/assets/images/arrow.png'),
                arrow2: require('@/assets/images/arrow.png')
            }
        }
    },
    methods: {
        isLeap(y) { // 是否是润年
            return (y % 100 !== 0 && y % 4 === 0) || (y % 400 === 0);
        },
        isDate(obj) { // 是否是日期格式
            return this.OS.call(obj === '[object Date]')
        },
        dateToString(date) {
            if(!this.isDate(date)) {
                return false
            }
            return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
        },
        getSiblingsMonth(y, m, n) { // 获取弟兄年月
            var d = new Date(y, m - 1)
            d.setMonth(m - 1 + n)
            return {
                y: d.getFullYear(),
                m: d.getMonth() + 1
            }
        },
        getDaysNum(y, m) { // 获取m月有几天
            let num = 31;
            switch (m) {
                case 2:
                    num = this.isLeap(y) ? 29 : 28;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    num = 30;
                    break;
            }
            return num;
        },
        getPrevMonth(y, m, n) {
            return this.getSiblingsMonth(y, m, 0 - (n || 1))
        },
        getNextMonth(y, m, n) {
            return this.getSiblingsMonth(y, m, n || 1)
        },
        getListMonth() { // 获取14个月的数据
            this.daySet = [] //
            // 生成前12个月的数据
            for(let i = 12; i >= -2; i--) {
                this.daySet.push(this.getDaysSet(new Date(this.curDays.year, this.curDays.month - (i + 2))))
            }
        },
        getDayItem(y, m, d, f) { // 填充数据
            let toDay = false // 是否是当天
            let cD = new Date()
            if(cD.getFullYear() === y && cD.getMonth() + 1 === m && cD.getDate() === d && f === 2) {
                toDay = true
                this.selectElement = new Date(y, m - 1, d)
            }
            let tDisabled
            if(this.calendarType == 'small') {
                tDisabled = 0
            } else {
                if(f === 2) {
                    tDisabled = 0
                } else {
                    tDisabled = 1
                }
            }
            let noCheck = true // 是否可以选中
            // if(this.dataList.length > 0) {
            //     this.dataList.forEach(item => {
            //         if(item == d) {
            //             noCheck = false
            //         }
            //     })
            // }
            return {
                dayNum: d,
                monthType: f,
                disabled: tDisabled, // 是否是当月
                noCheck: noCheck, // 是否可选
                toDay: toDay,
                nowDate: new Date(y, m - 1, d) // 当前日期
            }
        },
        getDaysSet(y, m) { // 获取某月显示的日期
            let year, month, firstWeek, daysNum, prevM, prevDiff, prevDaysNum, nextM,
                days = [] // 日期数据
            if(this.isDate(y)) {
                year = y.getFullYear()
                month = y.getMonth() + 1
            } else {
                year = Number(y)
                month = Number(m)
            }
            // 星期天则为7
            firstWeek = new Date(year, month - 1, 1).getDay() || 7
            prevDiff = firstWeek - this.startWeek
            daysNum = this.getDaysNum(year, month)
            prevM = this.getPrevMonth(year, month)
            prevDaysNum = this.getDaysNum(year, prevM.m)
            nextM = this.getNextMonth(year, month)
            // month flag
            let PREV_FLAG = 1,
                CURR_FLAG = 2,
                NEXT_FLAG = 3,
                count = 0
            // 上月最后几天
            for(let p = prevDaysNum - prevDiff + 1; p <= prevDaysNum; p++, count++) {
                days.push(this.getDayItem(prevM.y, prevM.m, p, PREV_FLAG))
            }
            // 本月天数
            for(let c = 1; c <= daysNum; c++, count++) {
                days.push(this.getDayItem(year, month, c, CURR_FLAG))
            }
            // 下月天数
            let c = (count % 7) === 0 ? count : (7 - (count % 7) + count)
            for (let n = 1, nl = c - count; n <= nl; n++) {
                days.push(this.getDayItem(nextM.y, nextM.m, n, NEXT_FLAG))
            }
            return days
        },
        getSmallCalendar(y, m, d) {
            let year, month, day, firstWeek,
                days = [] // 日期数据
            if(this.isDate(y)) {
                year = y.getFullYear()
                month = y.getMonth() + 1
                day = y.getDate()
            } else {
                year = Number(y)
                month = Number(m)
                day = Number(d)
            }
            let CURR_FLAG = 2,
                // NEXT_FLAG = 3,
                // PREV_FLAG = 1,
                count = 0
            // 星期天则为7
            firstWeek = new Date(year, month - 1, day).getDay() || 7
            // 在本周当天之前的日期
            for (let p = (firstWeek - 1); p > 0; p--, count++) {
                let tempD = new Date(year, month - 1, day - p)
                let pYear = tempD.getFullYear()
                let pMonth = tempD.getMonth() + 1
                let pDay = tempD.getDate()
                days.push(this.getDayItem(pYear, pMonth, pDay, CURR_FLAG))
            }
            // 当天日期
            days.push(this.getDayItem(year, month, day, CURR_FLAG))
            count++
            // 在本周当天之后的日期
            for (let n = 1; n <= (7 - count); n++) {
                let tempD = new Date(year, month - 1, day + n)
                let nYear = tempD.getFullYear()
                let nMonth = tempD.getMonth() + 1
                let nDay = tempD.getDate()
                days.push(this.getDayItem(nYear, nMonth, nDay, CURR_FLAG))
            }
            this.daySet.push(days)
        },
        slideChangeTransitionEnd() { // 滑动完成
            let swiper = this.swiper
            // 当前滑动到的日期
            let checkDate = this.daySet[swiper.activeIndex][6].nowDate
            this.curDays = {
                year: checkDate.getFullYear(),
                month: checkDate.getMonth() + 1
            }
            // 是否是第一页
            // if(swiper.isBeginning) {  // 由于体验问题不使用
                // let tempDays = this.getDaysSet(new Date(this.curDays.year, this.curDays.month - 1))
                // this.daySet.unshift(tempDays)
            // }
            // 是否是最后一页
            if(swiper.isEnd) {
                this.daySet.push(this.getDaysSet(new Date(this.curDays.year, this.curDays.month)))
            }

            this.$emit('onChangeMonth', checkDate)
        },
        slidePrev() { // 上一页
         this.imgs.arrow1 = require('@/assets/images/arrow-active.png')
            this.swiper.slidePrev()
        },
        slideNext() { // 下一页
            this.imgs.arrow2 =require('@/assets/images/arrow-active.png')
            this.swiper.slideNext()
     
        },
        endTouch(){
            this.imgs.arrow1 = require('@/assets/images/arrow.png')
            this.imgs.arrow2 = require('@/assets/images/arrow.png')

        },
        touchStart() { 
            let touch = event.touches[0]
            this.points.startY = touch.pageY
            this.points.startX = touch.pageX
        },
        touchMove() {
            // let touch = event.touches[0]
            // this.points.endX = touch.pageX
            // this.points.endY = touch.pageY
            
            // let pt = this.points,
            //     X = pt.endX - pt.startX,
            //     Y = pt.endY - pt.startY
            // if ( Math.abs(X) > Math.abs(Y) && X > 0 ) {
            //     console.log("left 2 right");
            // }
            // else if  ( Math.abs(X) > Math.abs(Y) && X < 0 ) {
            //     console.log("right 2 left");
            // }
            // else 
            // if  ( Math.abs(Y) > Math.abs(X) && Y > 0) {
            //     console.log("top 2 bottom")
            //     this.onTouchDown()
            // }
            // else if  ( Math.abs(Y) > Math.abs(X) && Y < 0 ) {
            //     console.log("bottom 2 top")
            //     this.onTouchUp()
            // }
            //  else{
            //     console.log("just touch");
            // }
        },
        onTouchUp() { // 向上滑
            // let activeIndex = this.swiper.activeIndex
            // let acitveDayIndex // 选中日期索引
            // let curDays = this.daySet[activeIndex]
            // curDays.forEach((day, index) => {
            //     if(this.dateToString(day.nowDate) == this.dateToString(this.selectElement)) {
            //         // console.log(index)
            //         acitveDayIndex = index
            //     }
            // })
            // let arr = []
            // for(let i = 0; i < 7; i++) {
            //     arr.push({
            //         dayNum: i + 1,
            //         monthType: 2,
            //         disabled: false,
            //         toDay: i == 3 ? true : false,
            //         nowDate: new Date()
            //     })
            // }
            // console.log(arr)
            // this.daySet[activeIndex] = arr
            // this.$forceUpdate()
            // this.swiper.detachEvents() //移除所有slide监听事件
            // this.swiper.attachEvents() //重新绑定所有监听事件。
            // return {
            //     dayNum: d,
            //     monthType: f,
            //     disabled: f === 2 ? 0 : 1, // 是否是当月
            //     toDay: toDay,
            //     nowDate: new Date(y, m - 1, d) // 当前日期
            // }
        },
        onTouchDown() { // 向下滑

        },
        touchEnd() { 
            // let pt = this.points,
            //     X = pt.endX - pt.startX,
            //     Y = pt.endY - pt.startY
            // if ( Math.abs(X) > Math.abs(Y) && X > 0 ) {
            //     console.log("left 2 right");
            // }
            // else if  ( Math.abs(X) > Math.abs(Y) && X < 0 ) {
            //     console.log("right 2 left");
            // }
            // else 
            // if  ( Math.abs(Y) > Math.abs(X) && Y > 0) {
            //     console.log("top 2 bottom");
            // }
            // else if  ( Math.abs(Y) > Math.abs(X) && Y < 0 ) {
            //     console.log("bottom 2 top");
            // }
            //  else{
            //     console.log("just touch");
            // }
        },
        onSelectDay(item) {
            // 除了当月其它月份不能点击, 可选日期
            if(item.monthType == 2 && !item.noCheck) {
                this.selectElement = item.nowDate
                // 暴露出方法
                this.$emit('onSelectDay', item.nowDate)
            }
        },
        onToggleType() { //切换日历类型
            // this.calendarType = this.calendarType === 'default' ? 'small' : 'default'
            if(this.calendarType === 'default') {
                this.calendarType = 'small'
                this.getSmallCalendar(new Date())
            } else {
                this.calendarType = 'default'
                this.getListMonth()
            }
            this.$forceUpdate()
        }
    },
    computed: {
        swiper() {
            return this.$refs.mySwiper.swiper
        }
    },
    watch: {
        dayList(value) {
            this.dayDateList = value
            const selectDate = this.daySet[this.swiper.activeIndex]
            selectDate.forEach(item => {
                if(item.disabled == 0 && item.monthType == 2) {
                    if(value.includes(dayjs(item.nowDate).format('DD'))) {
                        item.noCheck = false
                    } else {
                        item.noCheck = true
                    }
                }
            })
        }
    },
    mounted() {
        // 选择不同的日历类型
        if(this.calendarType == 'default') {
            this.getListMonth()
        } else {
            this.getSmallCalendar(new Date())
        }

        // current swiper instance
        // 然后你就可以使用当前上下文内的swiper对象去做你想做的事了
        // console.log('this is current swiper instance object', this.swiper)
        // this.swiper.slideTo(0, 1000, false)
    }
}
</script>
<style lang='less' scoped>
@import url("../assets/commonLess/variable.less");

.calendar {
    background: @whiteColor;
    padding: .15rem .2rem;
    .c__hd {
        display: flex;
        align-items: center;
        justify-content: space-between;
    }
    .c__date {
        color: #333;
        font-size: .24rem;
        // font-weight: bold;
        // span {
        //     padding-right: .08rem;
        //     font-size: .26rem;
        // }
    }
    .van-icon {
        margin-left: .1rem;
        width: .24rem;
        height: .24rem;
        font-size: .14rem;
        color: #c4c4c4;
        background: #eee;
        text-align: center;
        line-height: .24rem;
        border-radius: 50%;
        transition: all .2s ease;
        &:active {
            background: @mColor;
            color: #4eada7;
            color: #fff;
        }
    }

    .week-title {
        display: flex;
        align-items: center;
        justify-content: space-between;
        text-align: center;
        padding: .2rem 0 .1rem;
        color: #777;
        span {
            flex: 1;
            font-size: .16rem;
            color: @tFontColor;
            font-weight: 600;
        }
    }

    .tr {
        display: flex;
        align-items: center;
        text-align: center;
        font-size: .15rem;
        color: @mFontColor;
        // justify-content: space-around;
        flex-wrap: wrap;
    }
    .td {
        width: 14.2857%;
        margin-top: .03rem;
        &.small {
            span {
                background: #F6F8F9;
            }
        }

        span {
            position: relative;
            display: block;
            margin: 0 auto;
            width: .36rem;
            height: .36rem;
            background: transparent;
            border-radius: 50%;
            line-height: .36rem;
            font-weight: 500;
            &.noCheck {
                color: #ccc;
            }
            &.today::before {
                content: '今';
                display: block;
                width: calc(100% - 2px);
                height: calc(100% - 2px);
                background: #fff;
                color: @orangeColor;
                border: 1px solid @orangeColor;
                border-radius: 50%;
                position: absolute;
                left: 0;
                top: 0;
            }
            &.active {
                background: @mColor;
                color: @whiteColor;
                transition: all .2s ease;
            }
            &.disabled { // 如果不是当月则不显示
                color: transparent !important;
                background: #fff !important;
                &::before {
                    content: '';
                    color: #fff;
                    border: 1px solid #fff;
                }
            }
        }
    }

    .swiper-slide {
        transition: all .5s ease;
    }
    .arrow {
        width: .22rem;
        height: .22rem;

    }
    .arrow-left {
        transform: rotate(180deg);
        margin-right: .12rem;
    }
}
</style>