<template>
    <div class="ev_calendar_time">
        <div class="ev_calendar_weeks">
            <div class="ev_calendar_week" v-for="(item, index) in ['日', '一', '二', '三', '四', '五', '六']" :key="index">
                {{item}}
            </div>
        </div>
        <div class="ev_calendar_days">
            <div class="ev_calendar_days_item_box" v-for="(parentItem, parentIndex) in dates" :key="parentIndex">
                <div class="ev_calendar_year_month">{{parentItem.year}}-{{parentItem.month}}</div>
                <div class="ev_calendar_days_box">
                    <div class="ev_calendar_days_item"
                        v-for="(childItem, childIndex) in parentItem.days" 
                        :key="childIndex" 
                        @click="handleSelectDate(childItem, parentItem.month, parentItem.year)"
                        :class="{'hidden_item': !childItem.show, 
                                'border_radius_left': childItem.first || childItem.start || childItem.timestamp === reletExpireTimeAddOneToDay, 
                                'border_radius_right': childItem.last || childItem.end || childItem.select || childItem.timestamp === reletExpireTimeToDay, 
                                'border_radius_all': (childItem.end && childItem.first) || (childItem.last && childItem.start) || (calendarType === 'single' && childItem.select),
                                'select': childItem.select,
                                'middle': childItem.middle,
                                'disabled': childItem.disabled
                                }">
                        <div class="ev_calendar_days_item_top" :class="{'ev_calendar_days_item_top_color1': !childItem.middle && !childItem.select, 'ev_calendar_days_item_top_color2': (childItem.middle || childItem.select) && !childItem.disabled}">
                            {{dateTitle(childItem)}}
                        </div>
                        <div class="ev_calendar_days_item_middle">{{childItem.day}}</div>
                        <div class="ev_calendar_days_item_bottom"></div>
                    </div>
                </div>
            </div>
        </div>
        <div class="ev_date_picker">
            <picker-view :indicator-style="indicatorStyle" :value="value" @change="bindChange">
                <picker-view-column>
                    <div class="item" v-for="(item,index) in hours" :key="index">{{item}}点</div>
                </picker-view-column>
                <picker-view-column>
                    <div class="item" v-for="(item,index) in minutes" :key="index">{{item}}分</div>
                </picker-view-column>
            </picker-view>
        </div>
        <div class="confirm_btn">
            <button @click="handleConfirm()">确定</button>
        </div>
    </div>
</template>

<script>
const leapYear = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const commonYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

// 获取某月第某天是星期几
function getDay(month, year, index) {
  return new Date(year, month, index).getDay();
}

// 获取某月有几天
function getMonthLength(month, year) {
  if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) {
    return leapYear[month];
  } else {
    return commonYear[month];
  }
}

// 数字补位 1 -> 01
function prefixNum(num) {
  if (num < 10) {
    return "0" + num;
  } else {
    return "" + num;
  }
}
export default {
    props: {
        startTime: { // 开始时间（必传）
            default: new Date().getTime(),
            type: Number
        },
        currentTime: { // 当前时间（必传）
            default: new Date().getTime(),
            type: Number
        },
        reletExpireTime: { // 续租到期时间（续租时传）
            default: 0,//new Date().getTime() + 5*24*60*60*1000
            type: Number
        },
        calendarType: {
            default: 'single', // range,single
            type: String
        },
        /*
        1：I02-1页面，预约用车选择取车时间
        2：J02-1页面，预约用车选择还车时间
        3：G07-1页面，续租
        */
        businessType: { // 对应三种场景（必传）
            default: 1,
            type: Number
        }
    },
    data() {
        let hours = [];
        for (let i = 0; i < 24; i++) {
            hours.push(i);
        }
        let minutes = [];
        for (let i = 0; i < 60; i++) {
            minutes.push(i);
        }
        return {
            startYear: 0,
            startMonth: 0,
            startDay: 0,
            startHour: 0,
            startMinute: 0,
            endYear: 0,
            endMonth: 0,
            endDay: 0,
            endHour: 0,
            endMinute: 0,
            reletExpireYear: 0,
            reletExpireMonth: 0,
            reletExpireDay: 0,
            dates: [],
            currentTimeToDay: 0, // 当前时间精确到天时间戳
            reletExpireTimeToDay: 0, // 续租到期时间精确到天时间戳
            reletExpireTimeAddOneToDay: 0, // 续租到期时间后一天精确到天时间戳
            indicatorStyle: `height: 30px;color: #38B43C;`,
            hours: hours,
            staticHours: hours,
            minutes: minutes,
            staticMinutes: minutes,
            value: [0, 0],
            selectDate: {},
            selectHour: 0,
            selectMinute: 0
        }
    },
    methods: {
        initdates() {
            let startweek = getDay(this.startMonth, this.startYear, this.startDay);
            let endweek = getDay(this.endMonth, this.endYear, 1);
            let reletExpireTimestamp = this.reletExpireTime ? new Date(this.reletExpireYear, this.reletExpireMonth, this.reletExpireDay).getTime() : 0;
            let current = false; // 当前时间
            let start = false; // 某月的开始时间
            let middle = false; // 中间选中包含部分日期
            let end = false; // 某月的结束时间
            let disabled = false; // 续租时不可选择的天数
            let first = false; // 一个星期中开始的一天（即星期日）
            let last = false; // 一个星期中结束的一天（即星期六）
            let show = false; // 是否显示
            let select = false; // 选中的日期
            let timestamp = 0; // 日期对应的时间戳
            if (this.startMonth === this.endMonth) { // 一个月内
                let startDays = [];
                for (let i = 0; i < startweek; i++) { //填充空白的天数
                    startDays.push({
                        current: false,
                        start: false,
                        middle: false,
                        end: false,
                        disabled: false,
                        first: false,
                        last: false,
                        show: false,
                        day: 0,
                        select: false,
                        timestamp: 0
                    })
                }
                for (let i = this.startDay; i <= this.endDay; i++) { // 月份的天数渲染
                    let indexweek = getDay(this.startMonth, this.startYear, i);
                    let timestamp = new Date(this.startYear, this.startMonth, i).getTime();
                    first = indexweek === 0 ? true : false;
                    last = indexweek === 6 ? true : false;
                    current = timestamp === this.currentTimeToDay ? true : false;
                    start = i === this.startDay ? true : false;
                    end = i === this.endDay ? true : false;
                    if (this.businessType === 2) {
                        middle = i === this.startDay ? true : false;
                    }
                    if (reletExpireTimestamp) {
                        disabled = timestamp <= reletExpireTimestamp ? true : false;
                    }
                    startDays.push({
                        current: current,
                        start: start,
                        middle: middle,
                        end: end,
                        disabled: disabled,
                        first: first,
                        last: last,
                        show: true,
                        day: i,
                        select: select,
                        timestamp: timestamp
                    })
                }
                this.dates = [{
                    year: this.startYear,
                    month: prefixNum(this.startMonth + 1),
                    days: startDays
                }]
            }else {
                let startDays = [];
                let endDays = [];
                for (let i = 0; i < startweek; i++) { //填充开始月份空白的天数
                    startDays.push({
                        current: false,
                        start: false,
                        middle: false,
                        end: false,
                        disabled: false,
                        first: false,
                        last: false,
                        show: false,
                        day: 0,
                        select: false,
                        timestamp: 0
                    })
                }
                for (let i = this.startDay; i <= getMonthLength(this.startMonth, this.startYear); i++) { // 开始月份的天数渲染
                    let indexweek = getDay(this.startMonth, this.startYear, i);
                    let timestamp = new Date(this.startYear, this.startMonth, i).getTime();
                    first = indexweek === 0 ? true : false;
                    last = indexweek === 6 ? true : false;
                    current = timestamp === this.currentTimeToDay ? true : false;
                    start = i === this.startDay ? true : false;
                    end = i === getMonthLength(this.startMonth, this.startYear) ? true : false;
                    if (this.businessType === 2) {
                        middle = i === this.startDay ? true : false;
                    }
                    if (reletExpireTimestamp) {
                        disabled = timestamp <= reletExpireTimestamp ? true : false;
                    }
                    startDays.push({
                        current: current,
                        start: start,
                        middle: middle,
                        end: end,
                        disabled: disabled,
                        first: first,
                        last: last,
                        show: true,
                        day: i,
                        select: select,
                        timestamp: timestamp
                    })
                }
                for (let i = 0; i < endweek; i++) { //填充结束月份空白的天数
                    endDays.push({
                        current: false,
                        start: false,
                        middle: false,
                        end: false,
                        disabled: false,
                        first: false,
                        last: false,
                        show: false,
                        day: 0,
                        select: false,
                        timestamp: 0
                    })
                }
                for (let i = 1; i <= this.endDay; i++) { // 结束月份的天数渲染
                    let indexweek = getDay(this.endMonth, this.endYear, i);
                    let timestamp = new Date(this.endYear, this.endMonth, i).getTime();
                    first = indexweek === 0 ? true : false;
                    last = indexweek === 6 ? true : false;
                    current = timestamp === this.currentTimeToDay ? true : false;
                    start = i === 1 ? true : false;
                    end = i === this.endDay ? true : false;
                    if (reletExpireTimestamp) {
                        disabled = timestamp <= reletExpireTimestamp ? true : false;
                    }
                    endDays.push({
                        current: current,
                        start: start,
                        middle: middle,
                        end: end,
                        disabled: disabled,
                        first: first,
                        last: last,
                        show: true,
                        day: i,
                        select: select,
                        timestamp: timestamp
                    })
                }
                let startDates = {
                    year: this.startYear,
                    month: prefixNum(this.startMonth + 1),
                    days: startDays
                };
                let endDates = {
                    year: this.endYear,
                    month: prefixNum(this.endMonth + 1),
                    days: endDays
                };
                if (this.endMonth - 1 === this.startMonth || this.startYear !== this.endYear) { //两个月
                    this.dates = [startDates, endDates];
                }else if (this.endMonth - 2 === this.startMonth){ // 三个月
                    let middleDays = [];
                    let middleweek = getDay(this.endMonth - 1, this.endYear, 1);
                    for (let i = 0; i < middleweek; i++) { //填充中间月份空白的天数
                        middleDays.push({
                            current: false,
                            start: false,
                            middle: false,
                            end: false,
                            disabled: false,
                            first: false,
                            last: false,
                            show: false,
                            day: 0,
                            select: false,
                            timestamp: 0
                        })
                    }
                    for (let i = 1; i <= getMonthLength(this.endMonth - 1, this.endYear); i++) { // 中间月份的天数渲染
                        let indexweek = getDay(this.endMonth - 1, this.endYear, i);
                        let timestamp = new Date(this.endYear, this.endMonth - 1, i).getTime();
                        first = indexweek === 0 ? true : false;
                        last = indexweek === 6 ? true : false;
                        current = timestamp === this.currentTimeToDay ? true : false;
                        start = i === 1 ? true : false;
                        end = i === getMonthLength(this.endMonth - 1, this.endYear) ? true : false;
                        if (reletExpireTimestamp) {
                            disabled = timestamp <= reletExpireTimestamp ? true : false;
                        }
                        middleDays.push({
                            current: current,
                            start: start,
                            middle: middle,
                            end: end,
                            disabled: disabled,
                            first: first,
                            last: last,
                            show: true,
                            day: i,
                            select: select,
                            timestamp: timestamp
                        })
                    }
                    let middleDates = {
                        year: this.startYear,
                        month: prefixNum(this.endMonth),
                        days: middleDays
                    }
                    this.dates = [startDates, middleDates, endDates];
                }
            }
        },
        // 选择天数
        handleSelectDate(selectDate, selectMonth, selectYear) {
            if (!selectDate.disabled && selectDate.show) {
                this.selectDate = {
                    year: selectYear,
                    month: selectMonth,
                    day: selectDate.day
                }
                if (selectDate.start && Number(selectMonth) - 1 === this.startMonth) {
                    this.hours = [];
                    this.minutes = [];
                    for (let s = this.startHour; s < 24; s++) {
                        this.hours.push(s);
                    }
                    for (let e = this.startMinute; e < 60; e++) {
                        this.minutes.push(e);
                    }
                }
                if (selectDate.end && Number(selectMonth) - 1 === this.endMonth) {
                    this.hours = [];
                    this.minutes = [];
                    for (let s = 0; s < this.endHour; s++) {
                        this.hours.push(s);
                    }
                    for (let e = 0; e < this.endMinute; e++) {
                        this.minutes.push(e);
                    }
                }
                if (!(selectDate.start && Number(selectMonth) - 1 === this.startMonth) && !(selectDate.end && Number(selectMonth) - 1 === this.endMonth)) {
                    this.hours = this.staticHours;
                    this.minutes = this.staticMinutes;
                }
                for (let i = 0; i < this.dates.length; i++) {
                    let currentDate = this.dates[i];
                    for (let j = 0; j < currentDate.days.length; j++) {
                        let currentDay = currentDate.days[j];
                        this.dates[i].days[j].select = selectDate.day === currentDay.day && selectMonth === currentDate.month ? true : false;
                        if (this.calendarType === 'range') {
                            this.dates[i].days[j].middle = selectDate.timestamp > currentDay.timestamp ? true : false;
                        }
                    }
                }
            }
        },
        // 初始化变量
        initData() {
            let currentTime = new Date(this.currentTime);
            this.currentTimeToDay = new Date(currentTime.getFullYear(), currentTime.getMonth(), currentTime.getDate()).getTime();
            if (this.reletExpireTime) {
                let reletExpireTime = new Date(this.reletExpireTime);
                this.reletExpireTimeToDay = new Date(reletExpireTime.getFullYear(), reletExpireTime.getMonth(), reletExpireTime.getDate()).getTime();
                let reletExpireTimeAddOneToDay = new Date(this.reletExpireTime + 24*60*60*1000);
                this.reletExpireTimeAddOneToDay = new Date(reletExpireTimeAddOneToDay.getFullYear(), reletExpireTimeAddOneToDay.getMonth(), reletExpireTimeAddOneToDay.getDate()).getTime();
            }
            // 开始时间
            let startdate = new Date(this.startTime);
            startdate.setSeconds(0);
            startdate.setMilliseconds(0);
            let year = startdate.getFullYear();
            let month = startdate.getMonth();
            let day = startdate.getDate();
            let hour = startdate.getHours();
            let minute = startdate.getMinutes();
            this.startYear = year;
            this.startMonth = month;
            this.startDay = day;
            this.startHour = hour;
            this.startMinute = minute;
            // 结束时间
            let enddate = new Date(startdate.getTime() + 30*24*60*60*1000);
            enddate.setSeconds(0);
            enddate.setMilliseconds(0);
            let endyear = enddate.getFullYear();
            let endMonth = enddate.getMonth();
            let endDay = enddate.getDate();
            let endHour = enddate.getHours();
            let endMinute = enddate.getMinutes();
            this.endYear = endyear;
            this.endMonth = endMonth;
            this.endDay = endDay;
            this.endHour = endHour;
            this.endMinute = endMinute;
            // 续租到期时间
            if (this.reletExpireTime) {
                let reletExpireDate = new Date(this.reletExpireTime);
                reletExpireDate.setHours(0);
                reletExpireDate.setMinutes(0);
                reletExpireDate.setSeconds(0);
                reletExpireDate.setMilliseconds(0);
                let reletExpireYear = reletExpireDate.getFullYear();
                let reletExpireMonth = reletExpireDate.getMonth();
                let reletExpireDay = reletExpireDate.getDate();
                this.reletExpireYear = reletExpireYear;
                this.reletExpireMonth = reletExpireMonth;
                this.reletExpireDay = reletExpireDay;
            }
        },
        dateTitle(childItem) {
            let text = '';
            if (this.businessType === 1) {
                if (childItem.current) {
                    text = '今天';
                }
                if (childItem.select) {
                    text = '取车';
                }
            }else if (this.businessType === 2){
                if (childItem.start) {
                    text = '取车';
                }
                if (childItem.select) {
                    text = '还车';
                }
            }else if (this.businessType === 3) {
                if (childItem.current) {
                    text = '今天';
                }
                if (childItem.select) {
                    text = '续租';
                }
            }
            return text;
        },
        handleConfirm() {
            if (this.selectDate.year) {
                let timestamp = new Date(this.selectDate.year, Number(this.selectDate.month) - 1, Number(this.selectDate.day), this.selectHour, this.selectMinute).getTime();
                this.$emit('handleConfirm', timestamp)
            }else {
                uni.showToast({
                    title: '请选择日期',
                    icon: 'none',
                })
            }
        },
        bindChange: function (e) {
            const val = e.detail.value;
            this.selectHour = this.hours[val[0]];
            this.selectMinute = this.minutes[val[1]];
        }
    },
    mounted() {
        this.initData();
        this.initdates();
    }
}
</script>

<style lang="less" scoped>
@import './cCalendarCustom.less';
</style>
