<template>
  <div class="mc-datepicker" :class="{'is-disabled': disabled,'is-range': range,'is-week': isWeek}">
    <input class="mc-input_inner" 
      type="text"
      :name="name"
      :id="id"
      @click="togglePanel"
      :clearable="clearable"
      :value="range ? value[0] + add + value[1] : value"
      :placeholder="placeholder"
      :disabled="disabled"
      readonly />
    <i class="mc-input_icon mc-icon-date"></i>
    <template v-if="clearable">
      <template v-if="value!=''">
        <template v-if="showDel">
          <i v-if="!disabled" class="mc-input_icon mc-icon-close" @click="del"></i>
        </template>
      </template>
    </template>
    <transition v-if="!disabled" name="slideDown">
    <div class="mc-datepicker_calendar" v-show="panelState" :style="coordinates">
        <div class="mc-datepicker_header" v-show="panelType !== 'year'">
            <span @click="prevMonthPreview()" class="prev mc-icon-arrow-left" :class="{'is-disabled': !minDisable}"></span>
            <span class="up"><i @click="chType('year')">{{ tmpYear }}年</i><i @click="chType('month')">{{tmpMonth + 1 | month(language)}}月</i></span>
            <span @click="nextMonthPreview()" class="next mc-icon-arrow-right" :class="{'is-disabled': !maxDisable}"></span>
        </div>
        <div class="mc-datepicker_header" v-show="panelType === 'year'">
            <span @click="chYearRange(0)" class="prev mc-icon-arrow-left"></span>
            <span class="up"><i >{{ yearList[0] }}年</i> - <i>{{yearList[yearList.length - 1]}}年</i></span>
            <span @click="chYearRange(1)" class="next mc-icon-arrow-right"></span>
        </div>
        <ul class="mc-datepicker_yearList" v-show="panelType === 'year'">
          <li v-for="item in yearList"
              :class="{selected: isSelected('year', item), invalid: validateYear(item)}" 
              @click="selectYear(item)">{{item}}年
          </li>
        </ul>
        <ul class="mc-datepicker_monthList" v-show="panelType === 'month'">
          <li v-for="(item, index) in monthList"
              :class="{selected: isSelected('month', index), invalid: validateMonth(index)}" 
              @click="selectMonth(index)"
              :key="index">
              {{item | month(language)}}月
          </li>
        </ul>
        <div class="mc-datepicker_dateList" v-show="panelType === 'date'">
          <table width="100%" cellspacing="0" cellpadding="0">
            <thead class="weeks">
              <tr>
                <th v-for="item in weekList">{{item | week(language)}}</th>
              </tr>
            </thead>
            <tbody class="date" v-if="showWeek">
              <tr v-for="list in dateList">
                <td v-for="(item, index) in list"
                    :class="{preMonth: item.previousMonth, nextMonth: item.nextMonth,
                      invalid: validateDate(item),
                      'is-disabled': validateDate(item),
                    firstItem: (index % 7) === 0,
                    lastItem: (index % 7) === 6}"
                    @click="selectDate(item)"
                    :key="index">
                    <span :class="{selected: isSelected('date', item)}">{{item.value}}</span>
                </td>
              </tr>
            </tbody>
            <tbody class="date" v-else-if="isWeek">
              <tr v-for="(list , index) in dateList">
                <td v-for="(item, index) in list"
                    :class="{preMonth: item.previousMonth, nextMonth: item.nextMonth,
                      invalid: validateDate(item),
                      'is-disabled': validateDate(item)}"
                    @click="selectDate(item)"
                    :key="index">
                    <span :class="{selected: isSelected('date', list[0])||isSelected('date', list[1])||isSelected('date', list[2])||isSelected('date', list[3])||isSelected('date', list[4])||isSelected('date', list[5])||isSelected('date', list[6])}">{{item.value}}</span>
                </td>
              </tr>
            </tbody>
            <tbody class="date" v-else>
              <tr v-for="(list , index) in dateList">
                <td v-for="(item, index) in list"
                    :class="{preMonth: item.previousMonth, nextMonth: item.nextMonth,
                      invalid: validateDate(item),
                      'is-disabled': validateDate(item)}"
                    @click="selectDate(item)"
                    :key="index">
                    <span :class="{selected: isSelected('date', item)}">{{item.value}}</span>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
    </div>
    </transition>
  </div>
</template>
<script>
    export default {
        data () {
            let now = new Date()
            return {
                showCancel: false,
                panelState: false,
                panelType: 'date',
                coordinates: {},
                year: now.getFullYear(),
                month: now.getMonth(),
                date: now.getDate(),
                tmpYear: now.getFullYear(),
                tmpMonth: now.getMonth(),
                tmpDate: now.getDate(),
                tmpStartYear: now.getFullYear(),
                tmpStartMonth: now.getMonth(),
                tmpStartDate: now.getDate(),
                tmpEndYear: now.getFullYear(),
                tmpEndMonth: now.getMonth(),
                tmpEndDate: now.getDate(),
                minYear: Number,
                minMonth: Number,
                minDate: Number,
                maxYear: Number,
                maxMonth: Number,
                maxDate: Number,
                add:'',
                showDel:true,
                newDate:'',
                maxDisable:true,
                minDisable:true,
                dateDisable:true,
                yearList: Array.from({length: 12}, (value, index) => new Date().getFullYear() + index),
                monthList: [1, 2, 3 ,4 ,5, 6, 7 ,8, 9, 10, 11, 12],
                weekList: [0, 1, 2, 3, 4, 5, 6],
                rangeStart: false
            }
        },
        props: {
            language: {default: 'ch'},
            min: {default: '1970-01-01'},
            max: {default: '3016-01-01'},
            name: {
              type: String
            },
            id: {
              type: String
            },
            disabled: {
              type: Boolean,
              default: false
            },
            clearable:{
              type: Boolean,
              default: true
            },
            placeholder: {
              type: String
            },
            value: {
              type: [String, Array],
              default: ''
            },
            showWeek: {
              type: Boolean,
              default: false
            },
            range: {
              type: Boolean,
              default: false
            },
            isWeek: {
              type: Boolean,
              default: false
            }
        },
        methods: {
            togglePanel () {
              this.panelState = !this.panelState;
              this.rangeStart = false;
              this.panelType= 'date';
              this.newDate = this.date;
            },
            isSelected (type, item) {
                switch (type){
                    case 'year':
                        if(!this.range) return item === this.tmpYear
                        return (new Date(item, 0).getTime() >= new Date(this.tmpStartYear, 0).getTime() 
                            && new Date(item, 0).getTime() <= new Date(this.tmpEndYear, 0).getTime())
                    case 'month':
                        if(!this.range){
                          return item === this.tmpMonth;
                        } else {
                          return item === this.tmpMonth;
                        }
                        return (new Date(this.tmpYear, item).getTime() >= new Date(this.tmpStartYear, this.tmpStartMonth).getTime() 
                            && new Date(this.tmpYear, item).getTime() <= new Date(this.tmpEndYear, this.tmpEndMonth).getTime())
                    case 'date':
                        if(!this.range) {
                          return this.date === item.value && this.month === this.tmpMonth && item.currentMonth
                        }
                        let month = this.tmpMonth
                        item.previousMonth && month--
                        item.nextMonth && month++
                        return (new Date(this.tmpYear, month, item.value).getTime() >= new Date(this.tmpStartYear, this.tmpStartMonth, this.tmpStartDate).getTime() && new Date(this.tmpYear, month, item.value).getTime() <= new Date(this.tmpEndYear, this.tmpEndMonth, this.tmpEndDate).getTime())


                }
            },
            chType (type) {
                this.panelType = type
            },
            chYearRange (next) {
                if(next){
                    this.yearList = this.yearList.map((i) => i + 12)
                }else{
                    this.yearList = this.yearList.map((i) => i - 12)
                }
            },
            prevMonthPreview () {
              let minArr = this.min.split('-')
              this.minYear = Number(minArr[0])
              this.minMonth = Number(minArr[1])
              if (this.tmpYear==this.minYear&&this.tmpMonth==this.minMonth-1) {
                this.minDisable = false;
                return;
              }
              this.maxDisable = true;
              if (this.value!='') {
                this.tempYear = this.year;
              } else {
                this.tempYear = new Date().getFullYear();
              }
              if (this.tmpMonth === 0) {
                this.tmpMonth = 11;
                this.tmpYear -= 1;
              } else {
                this.tmpMonth -= 1;
              }
              this.date = this.tmpYear!=this.tempYear ? null : this.newDate;
                // this.tmpMonth = this.tmpMonth === 0 ? 11 : this.tmpMonth - 1
            },
            nextMonthPreview () {
              let maxArr = this.max.split('-')
              this.maxYear = Number(maxArr[0])
              this.maxMonth = Number(maxArr[1])
              if (this.tmpYear==this.maxYear&&this.tmpMonth==this.maxMonth-1) {
                this.maxDisable = false;
                return;
              }
              this.minDisable = true;
              if (this.value!='') {
                this.tempYear = this.year;
              } else {
                this.tempYear = new Date().getFullYear();
              };
              if (this.tmpMonth === 11) {
                this.tmpMonth = 0;
                this.tmpYear += 1;
              } else {
                this.tmpMonth += 1;
              }
              this.date = this.tmpYear!=this.tempYear ? null : this.newDate;
                // this.tmpMonth = this.tmpMonth === 11 ? 0 : this.tmpMonth + 1
            },
            selectYear (year) {
                if(this.validateYear(year)) return
                this.tmpYear = year
                this.panelType = 'month'
            },
            selectMonth (month) {
                if(this.validateMonth(month)) return;
                this.tmpMonth = month;
                this.panelType = 'date';
            },
            selectWeek ($event) {
              // $event.currentTarget.className="";
              console.log($event.currentTarget)
            },
            dateWeek(dateString){
              var da='';
              if(dateString==undefined){
                var now=new Date();
                var now_m=now.getMonth()+1;
                now_m=(now_m<10)?'0'+now_m:now_m;
                var now_d=now.getDate();
                now_d=(now_d<10)?'0'+now_d:now_d;
                da=now.getFullYear()+'-'+now_m+'-'+now_d;
                console.log(da);
              }else{
                da=dateString;//日期格式2015-12-30
                console.log(da);
              }  
              var date1 = new Date(da.substring(0,4), parseInt(da.substring(5,7)) - 1, da.substring(8,10));//当前日期
              var date2 = new Date(da.substring(0,4), 0, 1); //1月1号
              //获取1月1号星期（以周一为第一天，0周一~6周日）
              var dateWeekNum=date2.getDay();
              if(dateWeekNum<0){dateWeekNum=6;}
              if(dateWeekNum<4){
                //前移日期
                date2.setDate(date2.getDate()-dateWeekNum);
              }else{
                //后移日期
                date2.setDate(date2.getDate()+7-dateWeekNum);
              }
              var d = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
              if(d<0){
                var date3 = (date1.getFullYear()-1)+"-12-31";
                return getYearWeek(date3);
              }else{
                //得到年数周数
                var year=date1.getFullYear();
                var week=Math.ceil((d+1 )/ 7);
                console.log(year+"年第"+week+"周");
                return  week;
              }
            },
            selectDate (date) {
                setTimeout(() => {
                    if(this.validateDate(date)) return;
                    if(date.previousMonth){
                        if(this.tmpMonth === 0){
                            this.year -= 1;
                            this.tmpYear -= 1;
                            this.month = this.tmpMonth = 11;
                        }else{
                            this.month = this.tmpMonth - 1;
                            this.tmpMonth -= 1;
                        }
                    }else if(date.nextMonth){
                        if(this.tmpMonth === 11){
                            this.year += 1;
                            this.tmpYear += 1;
                            this.month = this.tmpMonth = 0;
                        }else{
                            this.month = this.tmpMonth + 1;
                            this.tmpMonth += 1;
                        }
                    }
                    if(!this.range && !this.isWeek){
                        this.year = this.tmpYear;
                        this.month = this.tmpMonth;
                        this.date = date.value;
                        let value = `${this.tmpYear}-${('0' + (this.month + 1)).slice(-2)}-${('0' + this.date).slice(-2)}`
                        this.$emit('input', value);
                        this.$emit('after-change', value);   //执行回调
                        this.panelState = false
                        this.showDel = true;
                    }else if(!this.range && this.isWeek){
                        this.year = this.tmpYear;
                        this.month = this.tmpMonth;
                        this.date = date.value;
                        let value = `${this.tmpYear}-${('0' + (this.month + 1)).slice(-2)}-${('0' + this.date).slice(-2)}`
                        let week = this.tmpYear+'年第'+this.dateWeek(value)+'周';
                        this.$emit('input', week);
                        this.$emit('after-change', value);   //执行回调
                        this.panelState = false
                        this.showDel = true;
                    }else if(this.range && !this.rangeStart){
                        this.tmpEndYear = this.tmpStartYear = this.tmpYear
                        this.tmpEndMonth = this.tmpStartMonth = this.tmpMonth
                        this.tmpEndDate = this.tmpStartDate = date.value
                        this.rangeStart = true
                    }else if(this.range && this.rangeStart){
                        this.tmpEndYear = this.tmpYear
                        this.tmpEndMonth = this.tmpMonth
                        this.tmpEndDate = date.value
                        this.showDel = true;

                        let d1 = new Date(this.tmpStartYear, this.tmpStartMonth, this.tmpStartDate).getTime(),
                            d2 = new Date(this.tmpEndYear, this.tmpEndMonth, this.tmpEndDate).getTime()
                        if(d1 > d2){
                            let tmpY, tmpM, tmpD
                            tmpY = this.tmpEndYear 
                            tmpM = this.tmpEndMonth
                            tmpD = this.tmpEndDate

                            this.tmpEndYear = this.tmpStartYear
                            this.tmpEndMonth = this.tmpStartMonth
                            this.tmpEndDate = this.tmpStartDate

                            this.tmpStartYear = tmpY
                            this.tmpStartMonth = tmpM
                            this.tmpStartDate = tmpD
                        }
                        let RangeStart = `${this.tmpStartYear}-${('0' + (this.tmpStartMonth + 1)).slice(-2)}-${('0' + this.tmpStartDate).slice(-2)}`
                        let RangeEnd = `${this.tmpEndYear}-${('0' + (this.tmpEndMonth + 1)).slice(-2)}-${('0' + this.tmpEndDate).slice(-2)}`

                        let value = [RangeStart, RangeEnd]
                        this.$emit('input', value)
                        this.add = ' 至 ';
                        this.$emit('after-change', value);   //执行回调
                        this.rangeStart = false
                        this.panelState = false
                    }
                }, 0)
            },
            validateYear (year) {
                return (year > this.maxYear || year < this.minYear) ? true : false
            },
            validateMonth (month) {
                if(new Date(this.tmpYear, month).getTime() >= new Date(this.minYear, this.minMonth - 1).getTime()
                    && new Date(this.tmpYear, month).getTime() <= new Date(this.maxYear, this.maxMonth - 1).getTime()){
                    return false
                }
                return true
            },
            validateDate (date) {
                let mon = this.tmpMonth
                if(date.previousMonth){
                    mon -= 1
                }else if(date.nextMonth){
                    mon += 1
                }
                if(new Date(this.tmpYear, mon, date.value).getTime() >= new Date(this.minYear, this.minMonth - 1, this.minDate).getTime()
                    && new Date(this.tmpYear, mon, date.value).getTime() <= new Date(this.maxYear, this.maxMonth - 1, this.maxDate).getTime()){
                    return false
                }
                return true
            },
            close (e) {
                if(!this.$el.contains(e.target)){
                    this.panelState = false
                    this.rangeStart = false
                }
            },
            del() {
                this.$emit('input', this.range ? ['',''] : '');
                this.add = '';
                this.minDisable = true;
                this.maxDisable = true;
                this.panelState = false;
                this.showDel = false;
                if (this.range) {
                  // 初始化区间开始和结束日期
                  this.tmpYear = this.tmpEndYear = this.tmpStartYear = new Date().getFullYear();
                  this.tmpMonth = this.tmpEndMonth = this.tmpStartMonth = new Date().getMonth();
                  this.date = this.tmpEndDate = this.tmpStartDate = new Date().getDate();
                } else {
                  // 初始化日期
                  this.tmpYear  = new Date().getFullYear();
                  this.tmpMonth = this.month = new Date().getMonth();
                  this.date = this.newDate = new Date().getDate();
                }
            }
        },
        watch: {
            min (v) {
                let minArr = v.split('-')
                this.minYear = Number(minArr[0])
                this.minMonth = Number(minArr[1])
                this.minDate = Number(minArr[2])
            },
            max (v) {
                let maxArr = v.split('-')
                this.maxYear = Number(maxArr[0])
                this.maxMonth = Number(maxArr[1])
                this.maxDate = Number(maxArr[2])
            },
            range (newVal, oldVal) {
                if(newVal === oldVal) return
                if(newVal && Object.prototype.toString.call(this.value).slice(8, -1) === 'String'){
                    this.$emit('input', ['', ''])
                }
                if(!newVal && Object.prototype.toString.call(this.value).slice(8, -1) === 'Array'){
                    this.$emit('input', '')
                }
            }
        },
        computed: {
            dateList () {
                let currentMonthLength = new Date(this.tmpYear, this.tmpMonth + 1, 0).getDate()
                let dateList = Array.from({length: currentMonthLength}, (val, index) => {
                    return {
                        currentMonth: true,
                        value: index + 1
                    }
                })
                let startDay = new Date(this.tmpYear, this.tmpMonth, 1).getDay()
                let previousMongthLength = new Date(this.tmpYear, this.tmpMonth, 0).getDate()

                for(let i = 0, len = startDay; i < len; i++){
                    dateList = [{previousMonth: true, value: previousMongthLength - i}].concat(dateList)
                }
                for(let i = dateList.length, item = 1; i < 42; i++, item++){
                    dateList[dateList.length] = {nextMonth: true, value: item,}
                }
                var result = [];
                for(var i=0,len=dateList.length;i<len;i+=7){
                    result.push(dateList.slice(i,i+7));
                 }
                // console.log(result)
                return result
            }
        },
        filters: {
            week: (item, lang) => {
                switch (lang) {
                    case 'en':
                        return {0: 'Su', 1: 'Mo', 2: 'Tu', 3: 'We', 4: 'Th', 5: 'Fr', 6: 'Sa'}[item]
                    case 'ch':
                        return {0: '日', 1: '一', 2: '二', 3: '三', 4: '四', 5: '五', 6: '六'}[item]
                    default:
                        return item
                }
            },
            month: (item, lang) => {
                switch (lang) {
                    case 'en':
                        return {1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun',
                         7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'}[item]
                    case 'ch':
                        return {1: '01', 2: '02', 3: '03', 4: '04', 5: '05', 6: '06',
                         7: '07', 8: '08', 9: '09', 10: '10', 11: '11', 12: '12'}[item]
                    default:
                        return item
                }
            }
        },
        mounted () {
            this.$nextTick(() => {
                if(this.$el.parentNode.offsetWidth + this.$el.parentNode.offsetLeft - this.$el.offsetLeft <= 300){
                    this.coordinates = {right: '0', top: `${window.getComputedStyle(this.$el.children[0]).offsetHeight + 4}px`}
                }else{
                    this.coordinates = {left: '0', top: `${window.getComputedStyle(this.$el.children[0]).offsetHeight + 4}px`}
                }
                let minArr = this.min.split('-')
                this.minYear = Number(minArr[0])
                this.minMonth = Number(minArr[1])
                this.minDate = Number(minArr[2])

                let maxArr = this.max.split('-')
                this.maxYear = Number(maxArr[0])
                this.maxMonth = Number(maxArr[1])
                this.maxDate = Number(maxArr[2])

                if(this.range){
                    if(Object.prototype.toString.call(this.value).slice(8, -1) !== 'Array'){
                        throw new Error('Binding value must be an array in range mode.')
                    }
                    if(this.value.length){
                        let rangeStart = this.value[0].split('-')
                        let rangeEnd = this.value[1].split('-')
                        this.tmpStartYear = Number(rangeStart[0])
                        this.tmpStartMonth = Number(rangeStart[1]) - 1
                        this.tmpStartDate = Number(rangeStart[2])

                        this.tmpEndYear = Number(rangeEnd[0])
                        this.tmpEndMonth = Number(rangeEnd[1]) - 1
                        this.tmpEndDate = Number(rangeEnd[2])
                        // 默认高亮到区间
                        let currentValue = this.value[0].split('-')
                        this.currentYear = Number(currentValue[0])
                        this.currentMonth = Number(currentValue[1]-1)
                        this.currentDate = Number(currentValue[2])
                        this.tmpYear = this.currentYear;
                        this.tmpMonth = this.currentMonth;
                        this.add = ' 至 ';
                    }else{
                        this.$emit('input', ['', '']);
                        this.tmpStartYear = new Date().getFullYear();
                        this.tmpStartMonth = new Date().getMonth();
                        this.tmpStartDate = new Date().getDate();
                    }
                }
                if (!this.range) {
                  if (this.value!='') {
                    // 高亮默认
                    let currentValue = this.value.split('-')
                    this.currentYear = Number(currentValue[0])
                    this.currentMonth = Number(currentValue[1]-1)
                    this.currentDate = Number(currentValue[2])
                    this.tmpYear = this.currentYear;
                    this.tmpMonth = this.currentMonth;
                    this.year = this.currentYear;
                    this.month = this.currentMonth;
                    this.date = this.currentDate;
                    this.newDate = this.currentDate;
                  } else {
                    // 初始化日期
                    this.tmpYear  = new Date().getFullYear();
                    this.tmpMonth = new Date().getMonth();
                    this.date = this.newDate = new Date().getDate();
                  }
                }
                if(!this.value){
                  this.$emit('input', '');
                }
                window.addEventListener('click', this.close)
            })
        },
        beforeDestroy () {
            window.removeEventListener('click', this.close)
        }
    }
</script>