import _extends from 'babel-runtime/helpers/extends';
import Carousel from '../carousel';
import CarouselItem from '../carousel-item';
import PickerView from '../picker-view';
import Button from '../button';
import Icon from '../icon';
import Toast from '../toast';
import { getDays, getPrevTime, getNextTime } from '../calendar/util';
import { dateFormat } from '../utils/dateUtil';
import { zeroComplete } from '../utils/numberUtil';
import { preventDefault } from '../_utils/dom/event';
import { doubleRaf } from '../_utils/dom/raf';
import './index.less';

var RangePickerView = {
    name: 'SnRangePickerView',

    props: {
        value: {
            type: Array
        },
        disabledDate: Function
    },
    data: function data() {
        return {
            height: '',
            beginDate: '',
            endDate: '',
            beginDateSelect: true,
            endDateSelect: false,
            selectedDate: [],
            selectedDay: '',
            weekList: ['日', '一', '二', '三', '四', '五', '六'],
            yearAndMonthList: [],
            showCalender: true,
            showMonthSelect: false,
            year: 0,
            month: 0,
            currentValue: '',
            currentDate: '',
            swiperList: [],
            swiperItemIndex: 0
        };
    },

    computed: {
        styleHeight: function styleHeight() {
            return this.height + 'px';
        }
    },
    watch: {
        value: function value(val) {
            this.currentValue = val;
        },
        selectedDay: function selectedDay(val, oldVal) {
            var beginDateSelect = this.beginDateSelect,
                endDateSelect = this.endDateSelect;

            if (beginDateSelect) {
                this.beginDate = val;
            } else if (endDateSelect) {
                this.endDate = val;
            }
        }
    },
    created: function created() {
        this.currentValue = this.value || [dateFormat(new Date(), 'YYYY/MM/DD'), dateFormat(new Date(), 'YYYY/MM/DD')];

        if (this.currentValue instanceof Array) {
            if (this.currentValue.length === 1) {
                var beginDate = this.currentValue[0];
                if (isNaN(beginDate) && !isNaN(Date.parse(beginDate))) {
                    beginDate = dateFormat(beginDate, 'YYYY/MM/DD');
                } else {
                    beginDate = dateFormat(new Date(), 'YYYY/MM/DD');
                }

                this.beginDate = beginDate;
                this.endDate = beginDate;
                this.selectedDay = beginDate;
            } else if (this.currentValue.length === 2) {
                var _beginDate = this.currentValue[0];
                var endDate = this.currentValue[1];
                if (_beginDate && isNaN(_beginDate) && !isNaN(Date.parse(_beginDate))) {
                    _beginDate = dateFormat(_beginDate, 'YYYY/MM/DD');
                } else {
                    _beginDate = dateFormat(new Date(), 'YYYY/MM/DD');
                }
                if (endDate && isNaN(endDate) && !isNaN(Date.parse(endDate))) {
                    endDate = dateFormat(endDate, 'YYYY/MM/DD');
                } else {
                    endDate = dateFormat(new Date(), 'YYYY/MM/DD');
                }

                this.beginDate = _beginDate;
                this.endDate = endDate;
                this.selectedDay = this.beginDate;
            }
        }
        var date = new Date(this.beginDate);
        var year = date.getFullYear(),
            month = date.getMonth();
        this.render(year, month);
        this.renderYearAndMonth(year, month);
    },
    mounted: function mounted() {
        /* 动态计算swiper高度 */
        this.getHeight();
    },

    methods: {
        getHeight: function getHeight() {
            var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
            this.height = windowWidth < 480 ? windowWidth * 0.94 : 360;
        },
        render: function render(year, month) {
            var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;

            this.year = year;
            this.month = month;

            /* 注入滑动数组 */
            this.renderCarousel(year, month, this.selectedDay);
        },

        /* 渲染日历数据 */
        renderCarousel: function renderCarousel(year, month, value) {
            var _this = this;

            var beginDate = this.beginDate,
                endDate = this.endDate,
                disabledDate = this.disabledDate;

            /* 生成总共需要的3个月数据 */

            var prevTime = getPrevTime(year, month);
            var nextTime = getNextTime(year, month);
            var prevMonth = getDays(_extends({}, prevTime, {
                value: value,
                rangeBegin: new Date(beginDate),
                rangeEnd: new Date(endDate),
                disabledDate: disabledDate
            }));
            var curMonth = getDays({
                year: year,
                month: month,
                value: value,
                rangeBegin: new Date(beginDate),
                rangeEnd: new Date(endDate),
                disabledDate: disabledDate
            });
            var nextMonth = getDays(_extends({}, nextTime, {
                value: value,
                rangeBegin: new Date(beginDate),
                rangeEnd: new Date(endDate),
                disabledDate: disabledDate
            }));

            this.$refs.carousel && this.$refs.carousel.swipeTo(0, { immediate: true });
            this.swiperItemIndex = 0;
            doubleRaf(function () {
                _this.swiperList = [];
                _this.swiperList = [curMonth, nextMonth, prevMonth];
            });
        },

        /* 根据指定日期生成上下20年年月数据 */
        renderYearAndMonth: function renderYearAndMonth(year, month) {
            var _date = new Date();
            var _year = _date.getFullYear();
            var yearList = [],
                monthList = [];
            // 加载1980后20年数据
            for (var i = 1980; i <= _year + 20; i++) {
                yearList.push('' + i);
            }
            // 加载12个月份
            for (var _i = 1; _i <= 12; _i++) {
                var _month2 = zeroComplete(_i);
                monthList.push('' + _month2);
            }

            this.yearAndMonthList = [{
                values: yearList,
                defaultIndex: 0
            }, {
                values: monthList,
                defaultIndex: 1
            }];
            this.selectedDate = ['' + year, '' + zeroComplete(month + 1)];
        },

        /* 上一页 */
        prev: function prev() {
            if (!this.minDate) {
                var swiperItemIndex = this.swiperItemIndex;
                var goIndex = swiperItemIndex - 1 >= 0 ? swiperItemIndex - 1 : 2;
                this.$refs.carousel.swipeTo(goIndex);
            }
        },

        /* 下一页 */
        next: function next() {
            if (!this.maxDate) {
                var swiperItemIndex = this.swiperItemIndex;
                var goIndex = swiperItemIndex + 1 <= 2 ? swiperItemIndex + 1 : 0;
                this.$refs.carousel.swipeTo(goIndex);
            }
        },
        go: function go(year, month) {
            this.render(year, month, true);
        },

        /* 选择日期 */
        select: function select(event, k1, k2, data) {
            preventDefault(event, true);
            var index = this.swiperItemIndex;
            var month = this.swiperList[index];
            var days = month.days;

            if (data.isDisabled) {
                return;
            }

            for (var row = 0; row < days.length; row++) {
                for (var day = 0; day < days[row].length; day++) {
                    if (row === k1 && day === k2) {
                        days[k1][k2].isCurrent = true;
                    } else {
                        days[row][day].isCurrent = false;
                    }
                }
            }

            this.selectedDay = data.formatedDate;
            /* 如果当前选择的为上一月日期或者是下一月日期，重绘日历 */
            if (data.isLastMonth || data.isNextMonth) {
                var date = new Date(data.formatedDate);
                this.swiperItemIndex = 0;
                this.$refs.carousel.swipeTo(0);
                this.render(date.getFullYear(), date.getMonth());
            }

            // 如果点击是开始时间，自动切换到结束时间视图
            if (this.beginDateSelect) {
                this.$refs.wrapper.swipeTo(1);
            }
        },

        /* 设置选中的天 */
        setSelectedDay: function setSelectedDay() {
            var currentDate = new Date(this.selectedDay);
            var day = currentDate.getDate();
            /* 当前月最大日期 */
            var selectedMonthMaxDate = new Date(this.year, this.month + 1, 0).getDate();
            var selectedDay = dateFormat(new Date(this.year, this.month, day < selectedMonthMaxDate ? day : selectedMonthMaxDate), 'YYYY/MM/DD');
            this.selectedDay = selectedDay;
            this.currentDate = selectedDay;

            for (var t = 0; t < this.swiperList.length; t++) {
                var month = this.swiperList[t];
                var days = month.days;
                for (var row = 0; row < days.length; row++) {
                    for (var _day = 0; _day < days[row].length; _day++) {
                        if (days[row][_day].formatedDate === selectedDay) {
                            this.swiperList[t].days[row][_day].isCurrent = true;
                        } else {
                            this.swiperList[t].days[row][_day].isCurrent = false;
                        }
                    }
                }
            }
        },

        /* 确认日期 */
        submit: function submit(event) {
            preventDefault(event, true);
            var beginDate = this.beginDate,
                endDate = this.endDate;

            if (!beginDate || beginDate === '') {
                Toast('请选择起始日期');
                return;
            }
            if (!endDate || endDate === '') {
                Toast('请选择结束日期');
                return;
            }
            if (+new Date(beginDate) > +new Date(endDate)) {
                Toast({
                    position: 'bottom',
                    message: '起始日期不能大于结束日期'
                });
                return;
            }

            // todo 判断时间段是否包含不可选日期，如果包含，则提示重新选择

            this.currentValue = [beginDate, endDate];
            console.log('[SnRangePickerView] submit == ', this.currentValue);
            this.$emit('change', this.currentValue);
        },

        // 开始结束面板切换
        onRangeViewChange: function onRangeViewChange(index) {
            if (index === 0) {
                this.beginDateSelect = true;
                this.endDateSelect = false;
                this.selectedDay = this.beginDate;
            } else {
                this.beginDateSelect = false;
                this.endDateSelect = true;
                this.selectedDay = this.endDate;
            }

            var date = new Date(this.selectedDay);
            this.selectedDate = ['' + date.getFullYear(), '' + zeroComplete(date.getMonth() + 1)];
            this.render(date.getFullYear(), date.getMonth(), true);
        },

        /* 日历onChange回调 */
        onCalendarChange: function onCalendarChange(currentIndex) {
            var _this2 = this;

            /* 滑动结束后执行选中滑动前选中的天 */
            if (currentIndex !== this.swiperItemIndex) {
                this.$nextTick(function () {
                    doubleRaf(function () {
                        var disabledDate = _this2.disabledDate;

                        var _year = _this2.year,
                            _month = _this2.month,
                            _currentValue = _this2.selectedDay;

                        _this2.year = _this2.swiperList[currentIndex].year;
                        _this2.month = _this2.swiperList[currentIndex].month;
                        _this2.selectedDate = ['' + _this2.year, '' + zeroComplete(_this2.month + 1)];
                        var prevTime = getPrevTime(_year, _month);
                        var prev2Time = getPrevTime(prevTime.year, prevTime.month);
                        var nextTime = getNextTime(_year, _month);
                        var next2Time = getNextTime(nextTime.year, nextTime.month);

                        var prev2Month = getDays(_extends({}, prev2Time, {
                            value: _currentValue,
                            rangeBegin: new Date(_this2.beginDate),
                            rangeEnd: new Date(_this2.endDate),
                            disabledDate: disabledDate
                        }));
                        var next2Month = getDays(_extends({}, next2Time, {
                            value: _currentValue,
                            rangeBegin: new Date(_this2.beginDate),
                            rangeEnd: new Date(_this2.endDate),
                            disabledDate: disabledDate
                        }));

                        /* 当前页为第一页 */
                        if (_this2.swiperItemIndex === 0) {
                            /* 下滑，进入第二页; 开始顺序 => [cur, next, prev], 结束顺序 => [cur, next, next2] */
                            if (currentIndex === 1) {
                                _this2.$set(_this2.swiperList, 2, next2Month);
                            } else {
                                /* 上滑，进入第三页; 开始顺序 => [cur, next, prev], 结束顺序 => [cur, prev2, prev] */
                                _this2.$set(_this2.swiperList, 1, prev2Month);
                            }
                        } else if (_this2.swiperItemIndex === 1) {
                            /* 当前页为第二页 */
                            /* 下滑，进入第三页; 开始顺序 => [prev, cur, next], 结束顺序 => [next2, cur, next] */
                            if (currentIndex === 2) {
                                _this2.$set(_this2.swiperList, 0, next2Month);
                            } else {
                                /* 上滑，进入第一页; 开始顺序 => [prev, cur, next], 结束顺序 => [prev, cur, prev2] */
                                _this2.$set(_this2.swiperList, 2, prev2Month);
                            }
                        } else if (_this2.swiperItemIndex === 2) {
                            /* 当前页为第三页 */
                            /* 下滑，进入第一页; 开始顺序 => [next, prev, cur], 结束顺序 => [next, next2, cur] */
                            if (currentIndex === 0) {
                                _this2.$set(_this2.swiperList, 1, next2Month);
                            } else {
                                /* 上滑，进入第二页; 开始顺序 => [next, prev, cur], 结束顺序 => [prev2, prev, cur] */
                                _this2.$set(_this2.swiperList, 0, prev2Month);
                            }
                        }
                        _this2.swiperItemIndex = currentIndex;

                        _this2.setSelectedDay();
                    });
                });
            }
        },

        /* 年月onChange回调 */
        onYearAndMonthChange: function onYearAndMonthChange(picker, value, index) {
            console.log('onYearAndMonthChange = ', value);
            this.selectedDate = value;
            if (value && value instanceof Array) {
                var year = parseInt(value[0]);
                var month = parseInt(value[1]);
                var selectedMonthMaxDate = new Date(year, month, 0).getDate();
                if (this.beginDateSelect) {
                    var day = new Date(this.beginDate).getDate();
                    this.beginDate = dateFormat(new Date(year, month - 1, day < selectedMonthMaxDate ? day : selectedMonthMaxDate), 'YYYY/MM/DD');
                } else if (this.endDateSelect) {
                    var _day2 = new Date(this.endDate).getDate();
                    this.endDate = dateFormat(new Date(year, month - 1, _day2 < selectedMonthMaxDate ? _day2 : selectedMonthMaxDate), 'YYYY/MM/DD');
                }
            }
        },

        /* 切换视图 */
        onViewChange: function onViewChange(type) {
            var _date = void 0;
            if (type === 'begin') {
                _date = this.beginDate;
                this.endDateSelect = false;

                if (this.beginDateSelect) {
                    if (this.showCalender) {
                        this.showCalender = false;
                        this.showMonthSelect = true;

                        this.$refs.datePicker.setValues(this.selectedDate);
                    } else {
                        this.showCalender = true;
                        this.showMonthSelect = false;
                    }
                } else {
                    this.beginDateSelect = true;
                    this.showCalender = true;
                    this.showMonthSelect = false;
                    this.$refs.wrapper.swipeTo(0);
                }
            } else if (type === 'end') {
                _date = this.endDate;
                this.beginDateSelect = false;

                if (this.endDateSelect) {
                    if (this.showCalender) {
                        this.showCalender = false;
                        this.showMonthSelect = true;

                        this.$refs.datePicker.setValues(this.selectedDate);
                    } else {
                        this.showCalender = true;
                        this.showMonthSelect = false;
                    }
                } else {
                    this.endDateSelect = true;
                    this.showCalender = true;
                    this.showMonthSelect = false;
                    this.$refs.wrapper.swipeTo(1);
                }
            }

            var date = _date ? new Date(_date) : new Date();
            this.selectedDay = _date;
            this.selectedDate = ['' + date.getFullYear(), '' + zeroComplete(date.getMonth() + 1)];
            this.render(date.getFullYear(), date.getMonth(), true);
        },
        valueFormat: function valueFormat(value) {
            return dateFormat(value, 'YYYY年MM月DD日');
        }
    },
    render: function render() {
        var _this3 = this;

        var h = arguments[0];
        var mode = this.mode,
            showMonthSelect = this.showMonthSelect,
            beginDateSelect = this.beginDateSelect,
            endDateSelect = this.endDateSelect,
            beginDate = this.beginDate,
            endDate = this.endDate,
            showCalender = this.showCalender,
            weekList = this.weekList,
            height = this.height,
            styleHeight = this.styleHeight,
            swiperList = this.swiperList,
            yearAndMonthList = this.yearAndMonthList;


        return h(
            'div',
            { 'class': 'sn-range-picker-view' },
            [h(
                'div',
                { 'class': 'sn-range-picker-view-header' },
                [h(
                    'div',
                    { 'class': 'sn-range-picker-view-tabs range-date' },
                    [h(
                        'div',
                        {
                            'class': {
                                'sn-range-picker-view-tabs-item': true,
                                active: beginDateSelect
                            },
                            on: {
                                'click': function click() {
                                    return _this3.onViewChange('begin');
                                }
                            }
                        },
                        [beginDate ? this.valueFormat(beginDate) : '请选择起始日期']
                    ), h(
                        'div',
                        { 'class': 'sn-range-picker-view-tabs-separator' },
                        [h(Icon, {
                            attrs: { type: 'minus' }
                        })]
                    ), h(
                        'div',
                        {
                            'class': {
                                'sn-range-picker-view-tabs-item': true,
                                highlight: true,
                                active: endDateSelect
                            },
                            on: {
                                'click': function click() {
                                    return _this3.onViewChange('end');
                                }
                            }
                        },
                        [endDate ? this.valueFormat(endDate) : '请选择结束日期']
                    )]
                ), h(
                    Button,
                    {
                        'class': 'sn-range-picker-view-btn',
                        attrs: { type: 'link'
                        },
                        on: {
                            'click': this.submit
                        }
                    },
                    ['\u786E\u5B9A']
                )]
            ), h(
                'div',
                {
                    'class': 'sn-calendar-weekday',
                    style: { visibility: showCalender ? 'visible' : 'hidden' }
                },
                [weekList.map(function (week) {
                    return h(
                        'div',
                        { 'class': 'sn-calendar-weekday-item' },
                        [h('div', [week])]
                    );
                })]
            ), h(
                'div',
                { 'class': 'sn-calendar-panel', style: { height: styleHeight } },
                [h(
                    Carousel,
                    {
                        ref: 'wrapper',
                        attrs: { loop: false,
                            'show-indicators': false,

                            mousewheelable: false
                        },
                        directives: [{
                            name: 'show',
                            value: showCalender
                        }],
                        on: {
                            'change': this.onRangeViewChange
                        }
                    },
                    [h(CarouselItem, [h(
                        Carousel,
                        {
                            ref: 'carousel',
                            'class': 'start',
                            attrs: { 'show-indicators': false,

                                vertical: true
                            },
                            on: {
                                'change': this.onCalendarChange
                            },
                            directives: [{
                                name: 'show',
                                value: showCalender
                            }],

                            style: { height: styleHeight }
                        },
                        [swiperList.map(function (month, k0) {
                            return h(
                                CarouselItem,
                                {
                                    style: {
                                        width: '100%',
                                        height: styleHeight
                                    }
                                },
                                [h(
                                    'div',
                                    { 'class': 'sn-calendar-date' },
                                    [month.year + '-' + month.month_str]
                                ), h(
                                    'div',
                                    {
                                        'class': 'sn-calendar-month',
                                        ref: 'month'
                                    },
                                    [month.days.map(function (row, k1) {
                                        return h(
                                            'div',
                                            { 'class': 'month-row' },
                                            [row.map(function (item, k2) {
                                                return h(
                                                    'div',
                                                    { 'class': 'day' },
                                                    [item.isCurMonth ? h(
                                                        'div',
                                                        {
                                                            'class': {
                                                                'day-pack': true,
                                                                'last-month': item.isLastMonth,
                                                                'next-month': item.isNextMonth
                                                            },
                                                            on: {
                                                                'click': function click(event) {
                                                                    return _this3.select(event, k1, k2, item);
                                                                }
                                                            }
                                                        },
                                                        [h(
                                                            'div',
                                                            {
                                                                'class': {
                                                                    today: item.isToday,
                                                                    active: item.isCurrent,
                                                                    'in-range': item.isInRange,
                                                                    disabled: item.isDisabled
                                                                }
                                                            },
                                                            [h(
                                                                'div',
                                                                { 'class': 'day-pack-cell' },
                                                                [h(
                                                                    'div',
                                                                    {
                                                                        'class': {
                                                                            middle: true,
                                                                            isHoliday: item.isHoliday,
                                                                            hidden: item.dayHide
                                                                        }
                                                                    },
                                                                    [item.isToday ? '今' : item.day]
                                                                )]
                                                            )]
                                                        )]
                                                    ) : null]
                                                );
                                            })]
                                        );
                                    })]
                                )]
                            );
                        })]
                    )]), h(CarouselItem, [h(
                        Carousel,
                        {
                            ref: 'carousel',
                            'class': 'end',
                            attrs: { 'show-indicators': false,

                                vertical: true
                            },
                            on: {
                                'change': this.onCalendarChange
                            },
                            directives: [{
                                name: 'show',
                                value: showCalender
                            }],

                            style: { height: styleHeight }
                        },
                        [swiperList.map(function (month, k0) {
                            return h(
                                CarouselItem,
                                {
                                    style: {
                                        width: '100%',
                                        height: styleHeight
                                    }
                                },
                                [h(
                                    'div',
                                    { 'class': 'sn-calendar-date' },
                                    [month.year + '-' + month.month_str]
                                ), h(
                                    'div',
                                    {
                                        'class': 'sn-calendar-month',
                                        ref: 'month'
                                    },
                                    [month.days.map(function (row, k1) {
                                        return h(
                                            'div',
                                            { 'class': 'month-row' },
                                            [row.map(function (item, k2) {
                                                return h(
                                                    'div',
                                                    { 'class': 'day' },
                                                    [item.isCurMonth ? h(
                                                        'div',
                                                        {
                                                            'class': {
                                                                'day-pack': true,
                                                                'last-month': item.isLastMonth,
                                                                'next-month': item.isNextMonth
                                                            },
                                                            on: {
                                                                'click': function click(event) {
                                                                    return _this3.select(event, k1, k2, item);
                                                                }
                                                            }
                                                        },
                                                        [h(
                                                            'div',
                                                            {
                                                                'class': {
                                                                    today: item.isToday,
                                                                    active: item.isCurrent,
                                                                    'in-range': item.isInRange,
                                                                    disabled: item.isDisabled
                                                                }
                                                            },
                                                            [h(
                                                                'div',
                                                                { 'class': 'day-pack-cell' },
                                                                [h(
                                                                    'div',
                                                                    {
                                                                        'class': {
                                                                            middle: true,
                                                                            isHoliday: item.isHoliday,
                                                                            hidden: item.dayHide
                                                                        }
                                                                    },
                                                                    [item.isToday ? '今' : item.day]
                                                                )]
                                                            )]
                                                        )]
                                                    ) : null]
                                                );
                                            })]
                                        );
                                    })]
                                )]
                            );
                        })]
                    )])]
                ), h(
                    'div',
                    {
                        'class': {
                            'date-select': true,
                            'single-col': mode === 'year' || mode === 'month'
                        },
                        directives: [{
                            name: 'show',
                            value: showMonthSelect
                        }],

                        style: { height: height }
                    },
                    [h(PickerView, {
                        ref: 'datePicker',
                        attrs: { visibleItemCount: 7,
                            columns: yearAndMonthList
                        },
                        on: {
                            'change': this.onYearAndMonthChange
                        }
                    })]
                )]
            )]
        );
    }
};

RangePickerView.install = function (Vue) {
    Vue.component(RangePickerView.name, RangePickerView);
};

export default RangePickerView;