import { getDateRect, isSameDate, getMonthDateRect, isValidDate, getDate } from '../date'; 
 | 
export default class TCalendar { 
 | 
    constructor(options = {}) { 
 | 
        this.type = 'single'; 
 | 
        Object.assign(this, options); 
 | 
        if (!this.minDate) 
 | 
            this.minDate = getDate(); 
 | 
        if (!this.maxDate) 
 | 
            this.maxDate = getDate(6); 
 | 
    } 
 | 
    getTrimValue() { 
 | 
        const { value, type } = this; 
 | 
        const format = (val) => { 
 | 
            if (val instanceof Date) 
 | 
                return val; 
 | 
            if (typeof val === 'number') 
 | 
                return new Date(val); 
 | 
            return new Date(); 
 | 
        }; 
 | 
        if (type === 'single' && isValidDate(value)) 
 | 
            return format(value); 
 | 
        if (type === 'multiple' || type === 'range') { 
 | 
            if (Array.isArray(value)) { 
 | 
                const isValid = value.every((item) => isValidDate(item)); 
 | 
                return isValid ? value.map((item) => format(item)) : []; 
 | 
            } 
 | 
            return []; 
 | 
        } 
 | 
    } 
 | 
    getDays() { 
 | 
        const raw = '日一二三四五六'; 
 | 
        const ans = []; 
 | 
        let i = this.firstDayOfWeek % 7; 
 | 
        while (ans.length < 7) { 
 | 
            ans.push(raw[i]); 
 | 
            i = (i + 1) % 7; 
 | 
        } 
 | 
        return ans; 
 | 
    } 
 | 
    getMonths() { 
 | 
        const ans = []; 
 | 
        const selectedDate = this.getTrimValue(); 
 | 
        const { minDate, maxDate, type, format } = this; 
 | 
        let { year: minYear, month: minMonth, time: minTime } = getDateRect(minDate); 
 | 
        const { year: maxYear, month: maxMonth, time: maxTime } = getDateRect(maxDate); 
 | 
        const calcType = (year, month, date) => { 
 | 
            const curDate = new Date(year, month, date, 23, 59, 59); 
 | 
            if (type === 'single' && selectedDate) { 
 | 
                if (isSameDate({ year, month, date }, selectedDate)) 
 | 
                    return 'selected'; 
 | 
            } 
 | 
            if (type === 'multiple' && selectedDate) { 
 | 
                const hit = selectedDate.some((item) => isSameDate({ year, month, date }, item)); 
 | 
                if (hit) { 
 | 
                    return 'selected'; 
 | 
                } 
 | 
            } 
 | 
            if (type === 'range' && selectedDate) { 
 | 
                if (Array.isArray(selectedDate)) { 
 | 
                    const [startDate, endDate] = selectedDate; 
 | 
                    if (startDate && isSameDate({ year, month, date }, startDate)) 
 | 
                        return 'start'; 
 | 
                    if (endDate && isSameDate({ year, month, date }, endDate)) 
 | 
                        return 'end'; 
 | 
                    if (startDate && endDate && curDate.getTime() > startDate.getTime() && curDate.getTime() < endDate.getTime()) 
 | 
                        return 'centre'; 
 | 
                } 
 | 
            } 
 | 
            const minCurDate = new Date(year, month, date, 0, 0, 0); 
 | 
            if (curDate.getTime() < minTime || minCurDate.getTime() > maxTime) { 
 | 
                return 'disabled'; 
 | 
            } 
 | 
            return ''; 
 | 
        }; 
 | 
        while (minYear < maxYear || (minYear === maxYear && minMonth <= maxMonth)) { 
 | 
            const target = getMonthDateRect(new Date(minYear, minMonth, 1)); 
 | 
            const months = []; 
 | 
            for (let i = 1; i <= 31; i++) { 
 | 
                if (i > target.lastDate) 
 | 
                    break; 
 | 
                const dateObj = { 
 | 
                    date: new Date(minYear, minMonth, i), 
 | 
                    day: i, 
 | 
                    type: calcType(minYear, minMonth, i), 
 | 
                }; 
 | 
                months.push(format ? format(dateObj) : dateObj); 
 | 
            } 
 | 
            ans.push({ 
 | 
                year: minYear, 
 | 
                month: minMonth, 
 | 
                months, 
 | 
                weekdayOfFirstDay: target.weekdayOfFirstDay, 
 | 
            }); 
 | 
            const curDate = getDateRect(new Date(minYear, minMonth + 1, 1)); 
 | 
            minYear = curDate.year; 
 | 
            minMonth = curDate.month; 
 | 
        } 
 | 
        return ans; 
 | 
    } 
 | 
    select({ cellType, year, month, date }) { 
 | 
        const { type } = this; 
 | 
        const selectedDate = this.getTrimValue(); 
 | 
        if (cellType === 'disabled') 
 | 
            return; 
 | 
        const selected = new Date(year, month, date); 
 | 
        this.value = selected; 
 | 
        if (type === 'range' && Array.isArray(selectedDate)) { 
 | 
            if (selectedDate.length === 1 && selected > selectedDate[0]) { 
 | 
                this.value = [selectedDate[0], selected]; 
 | 
            } 
 | 
            else { 
 | 
                this.value = [selected]; 
 | 
            } 
 | 
        } 
 | 
        else if (type === 'multiple' && Array.isArray(selectedDate)) { 
 | 
            const newVal = [...selectedDate]; 
 | 
            const index = selectedDate.findIndex((item) => isSameDate(item, selected)); 
 | 
            if (index > -1) { 
 | 
                newVal.splice(index, 1); 
 | 
            } 
 | 
            else { 
 | 
                newVal.push(selected); 
 | 
            } 
 | 
            this.value = newVal; 
 | 
        } 
 | 
        return this.value; 
 | 
    } 
 | 
} 
 |