<!-- @desc:月份组件  @auth:周兴  @time:2023/7/7 10:46 -->
<template>
  <Poptip popper-class="month-popper-class" class="month-popper-class" trigger="click" transfer placement="bottom-start"
          v-model="visible">
    <Input ref="input" v-model="model" :readonly="readonly" @on-click="handleClickInput" @on-blur="chooseDatas"
           :placeholder="placeholderData"/>
    <Icon class="calendar-class" type="iconfont iconfont icon-calendar"/>
    <!--内容-->
    <div slot="content">
      <div class="month-class">
        <!--左侧快捷-->
        <div class="month-left-class">
          <div class="month-left-item-class" v-for="(item,index) in shortCutData" :key="index"
               @click="chooseMonthsByShortCut(item)">
            {{ item.text }}
          </div>
        </div>
        <!--右侧月份-->
        <div class="month-content">
          <!--年份-->
          <div class="month-title-class">
            <!--开始年份-->
            <div class="month-title-item-class">
              <div class="item-arrow-start-class" @click="handleChangeYear('before')">«
              </div>
              <div class="item-year-start-class">{{ startYear + '年' }}</div>
            </div>
            <!--结束年份-->
            <div class="month-title-item-class">
              <div class="item-year-end-class">{{ endYear + '年' }}</div>
              <div class="item-arrow-end-class" @click="handleChangeYear('next')">»
              </div>
            </div>
          </div>
          <!--月份-->
          <div class="month-total-class">
            <!--开始月份-->
            <div class="month-item-class">
              <DkRow>
                <!--最后一条样式不能覆盖-->
                <DkCol v-for="(item,index) in monthData" :key="index" :span="8"
                       :class-name="(item[startYear] && (choosedMonths.length !== 2 || choosedMonths.length ==0
                       || (choosedMonths.length == 2 && choosedMonths[1].yearMonth !== startYear + '-' + item.value )))?'btn-class-between':''">
                  <DkButton :ref="'month-' + startYear + '-' + item.value"
                            :type="checkCheckedMonth(startYear,item.value)?'primary':'default'"
                            class="btn-class"
                            :class="(item[startYear] && (choosedMonths.length !== 2 || choosedMonths.length ==0
                       || (choosedMonths.length == 2 && choosedMonths[1].yearMonth !== startYear + '-' + item.value )))?'btn-class-between':''"
                            @mouseenter.native="handleMouseEnter(Object.assign($event,{item,item,year:startYear}))"
                            @click="handleClickMonth(item,startYear)">
                    <div style="display: flex">{{ item.text }}
                      <div style="margin-top: -5px;" v-if="thisMonth === startYear + '-' + item.value">●</div>
                    </div>
                  </DkButton>
                </DkCol>
              </DkRow>
            </div>
            <!--结束月份-->
            <div class="month-item-class">
              <DkRow>
                <DkCol v-for="(item,index) in monthData" :key="index" :span="8"
                       :class-name="(item[endYear] && (choosedMonths.length !== 2 || choosedMonths.length ==0
                       || (choosedMonths.length == 2 && choosedMonths[1].yearMonth !== endYear + '-' + item.value )))?'btn-class-between':''">
                  <DkButton
                    :type="checkCheckedMonth(endYear,item.value)?'primary':'default'"
                    class="btn-class"
                    :class="(item[endYear] && (choosedMonths.length !== 2 || choosedMonths.length ==0
                       || (choosedMonths.length == 2 && choosedMonths[1].yearMonth !== endYear + '-' + item.value )))?'btn-class-between':''"
                    @mouseenter.native="handleMouseEnter(Object.assign($event,{item,item,year:endYear}))"
                    @click="handleClickMonth(item,endYear)">
                    <div style="display: flex">{{ item.text }}
                      <div style="margin-top: -5px;" v-if="thisMonth === endYear + '-' + item.value">●</div>
                    </div>
                  </DkButton>
                </DkCol>
              </DkRow>
            </div>
          </div>
        </div>
      </div>
    </div>
  </Poptip>
</template>

<script>
export default {
  name: "dk-month-picker-pop",
  inject: {
    prop: {
      type: String,
      default: null
    },
    dkFormItem: {
      type: Object,
      default: null
    }
  },
  props: {
    // 组件的值
    value: {
      type: [String, Array],
      default: null
    },
    //提示信息
    placeholder: {
      type: String,
      default: null
    },
    // 分隔符
    separator: {
      type: String,
      default: '～'
    },
    // 只读
    readonly: {
      type: Boolean,
      default: false
    },
  },
  data() {
    return {
      model: null,
      rightModel: {},
      placeholderData: null,
      startYear: 2023,// 开始年份
      endYear: 2024,// 结束年份
      thisMonth: null,// 当前月份
      chooseMonths: [], // 选择月份
      choosedMonths: [],// 已选择月份
      betweenMonths: {},// 期间月份
      visible: false,// pop是否显示
      clickFlag: false,
      monthData: [
        {value: 1, text: '1月'},
        {value: 2, text: '2月'},
        {value: 3, text: '3月'},
        {value: 4, text: '4月'},
        {value: 5, text: '5月'},
        {value: 6, text: '6月'},
        {value: 7, text: '7月'},
        {value: 8, text: '8月'},
        {value: 9, text: '9月'},
        {value: 10, text: '10月'},
        {value: 11, text: '11月'},
        {value: 12, text: '12月'},
      ],
      // 左侧快捷
      shortCutData: [
        {value: 1, text: '本月'},
        {value: 2, text: '上月'},
        {value: 3, text: '近三月'},
        {value: 4, text: '本季度'},
      ]
    }
  },
  watch: {
    model(n, o) {
      if (n) {
        // 清除提示信息
        this.clearErrMessage()
      }
      this.$emit('input', n)
    },
    visible(n, o) {
      if (n) {
        // 把开始年份设置到第一个日期
        if (this.choosedMonths && this.choosedMonths.length > 0) {
          this.startYear = this.choosedMonths[0].year;
          this.endYear = this.startYear + 1;
        }
      }
    },
  },
  methods: {
    /**
     * @desc   : 改变年份
     * @author : 周兴
     * @date   : 2023/7/10 9:27
     */
    handleChangeYear(type) {
      // 向前
      if (type === 'before') {
        this.startYear = this.startYear - 1;
        this.endYear = this.endYear - 1;
      } else {
        this.startYear = this.startYear + 1;
        this.endYear = this.endYear + 1;
      }
    },
    /**
     * @desc   : 判断选中的月份
     * @author : 周兴
     * @date   : 2023/7/7 15:36
     */
    checkCheckedMonth(year, month) {
      // 先判断当前
      let flag = this.chooseMonths.filter(it => it.yearMonth === (year + '-' + month)).length > 0
      if (!flag) {
        // 当前没有的清空判断已选
        flag = this.choosedMonths.filter(it => it.yearMonth === (year + '-' + month)).length > 0
      }
      return flag;
    },
    /**
     * @desc   : 判断之间的月份
     * @author : 周兴
     * @date   : 2023/7/7 16:23
     */
    checkBetweenMonth(year, month) {
      let date = new Date(year + '-' + month + '-1');
      if (this.betweenMonths.min && this.betweenMonths.max
        && date > this.betweenMonths.min && date <= this.betweenMonths.max) {
        return true;
      }
      return false;
    },
    /**
     * @desc   : 点击input组件
     * @author : 周兴
     * @date   : 2023/7/7 15:17
     */
    handleClickInput(e) {
      this.visible = true;
    },
    /**
     * @desc   : 离开校验日期格式是否正确
     * @author : 周兴
     * @date   : 2023/7/10 16:52
     */
    chooseDatas(e) {
      setTimeout(() => {
        if (!this.model || this.clickFlag) return;
        let rightModel = this.rightModel
        let values = this.model.split(this.separator);
        let startMonth = {};
        let endMonth = {};
        if (values && values.length === 2) {
          try {
            let v1 = values[0].split('-');
            let v2 = values[1].split('-');
            // 非法输入，恢复到原值
            if (!v1 || v1.length != 2 || !v2 || v2.length != 2) {
              this.model = rightModel?.model;
              this.chooseMonths = rightModel?.choosedMonths?.copy();
              startMonth = this.chooseMonths[0]
              endMonth = this.chooseMonths[1]
            } else {
              let date1 = new Date(values[0] + '-1');
              let date2 = new Date(values[1] + '-1');
              if (date1 < date2) {
                startMonth.date = date1;
                startMonth.year = date1.getFullYear();
                startMonth.month = date1.getMonth() + 1;
                endMonth.date = date2;
                endMonth.year = date2.getFullYear();
                endMonth.month = date2.getMonth() + 1;
              } else {
                startMonth.date = date2;
                startMonth.year = date2.getFullYear();
                startMonth.month = date2.getMonth() + 1;
                endMonth.date = date1;
                endMonth.year = date1.getFullYear();
                endMonth.month = date1.getMonth() + 1;
              }
              startMonth.yearMonth = startMonth.year + '-' + startMonth.month
              endMonth.yearMonth = endMonth.year + '-' + endMonth.month
            }
          } catch (e) {
            this.model = rightModel?.model;
            this.chooseMonths = rightModel?.choosedMonths?.copy();
            startMonth = this.chooseMonths[0]
            endMonth = this.chooseMonths[1]
          }
        }
        if (!values || values.length !== 2) {
          // 恢复为原来的值
          this.model = rightModel?.model;
          this.chooseMonths = rightModel?.choosedMonths?.copy();
          startMonth = this.chooseMonths[0]
          endMonth = this.chooseMonths[1]
        }
        // 选择日期
        this._chooseDates(startMonth, endMonth);
      }, 300)
    },
    /**
     * @desc   : 恢复月份的值
     * @author : 周兴
     * @date   : 2023/7/10 11:49
     */
    restoreMonthData() {
      // 清除掉value 和text之外的数据
      this.monthData = this.monthData.map(m => {
        return {
          value: m.value,
          text: m.text
        }
      })
    },
    /**
     * @desc   : 鼠标移入
     * @author : 周兴
     * @date   : 2023/7/7 16:07
     */
    handleMouseEnter(e) {
      if (this.chooseMonths.length === 1) {
        // 清除掉value 和text之外的数据
        this.restoreMonthData();
        let date1 = new Date(this.chooseMonths[0].yearMonth + '-1')
        let date2 = new Date(e.year + '-' + e.item.value + '-1')
        let betweenMonths = {}
        if (date1 < date2) {
          betweenMonths.min = date1
          betweenMonths.max = date2
        } else {
          betweenMonths.min = date2
          betweenMonths.max = date1
        }
        // 设置只见的月份
        this.setBetweenMonth(betweenMonths);
      }
    },
    /**
     * @desc   : 设置之间的月份
     * @author : 周兴
     * @date   : 2023/7/10 11:44
     */
    setBetweenMonth(betweenMonths) {
      if(typeof betweenMonths.min === 'string'){
        betweenMonths.min = new Date(betweenMonths.min)
      }
      if(typeof betweenMonths.max === 'string'){
        betweenMonths.max = new Date(betweenMonths.max)
      }
      let date = betweenMonths.min.addMonths(1)
      let filters = []
      while (date <= betweenMonths.max) {
        filters = this.monthData.filter(it => it.value === (date.getMonth() + 1))
        if (filters && filters.length > 0) {
          this.$set(filters[0], date.getFullYear(), true);
        }
        date = date.addMonths(1)
      }
    },
    /**
     * @desc   : 快捷选择数据
     * @author : 周兴
     * @date   : 2023/7/10 11:15
     */
    chooseMonthsByShortCut(e) {
      let startMonth = {};
      let endMonth = {};
      // 本月
      if (e.value === 1) {
        let date = new Date();
        startMonth.year = date.getFullYear();
        startMonth.month = date.getMonth() + 1;
        startMonth.yearMonth = startMonth.year + '-' + startMonth.month
        startMonth.date = date;
        endMonth = {...startMonth};
      } else if (e.value === 2) { // 上月
        let date = new Date();
        date = date.addMonths(-1);
        endMonth.year = date.getFullYear();
        endMonth.month = date.getMonth() + 1;
        endMonth.yearMonth = endMonth.year + '-' + endMonth.month
        endMonth.date = date;
        startMonth = {...endMonth};
      } else if (e.value === 3) { // 近三月
        let date = new Date();
        endMonth.year = date.getFullYear();
        endMonth.month = date.getMonth() + 1;
        endMonth.yearMonth = endMonth.year + '-' + endMonth.month
        endMonth.date = date;
        let startDate = date.addMonths(-3);
        startMonth.year = startDate.getFullYear();
        startMonth.month = startDate.getMonth() + 1;
        startMonth.yearMonth = startMonth.year + '-' + startMonth.month
        startMonth.date = startDate;
      } else if (e.value === 4) { // 本季度
        let date = new Date();
        let year = date.getFullYear()
        let month = date.getMonth() + 1
        const currQuarter = Math.floor((month % 3 === 0 ? (month / 3) : (month / 3 + 1)))

        if (currQuarter === 1) { // 第一季度
          endMonth.month = 3;
          startMonth.month = 1;
        } else if (currQuarter === 2) { // 第二季度
          endMonth.month = 6;
          startMonth.month = 4;
        } else if (currQuarter === 3) { // 第三季度
          endMonth.month = 9;
          startMonth.month = 7;
        } else {  // 第四季度
          endMonth.month = 12;
          startMonth.month = 10;
        }
        endMonth.year = year;
        startMonth.year = year;
        startMonth.date = new Date(year, startMonth.month - 1, 1);
        endMonth.yearMonth = endMonth.year + '-' + endMonth.month
        endMonth.date = new Date(year, endMonth.month - 1, 1);
        startMonth.yearMonth = startMonth.year + '-' + startMonth.month
      }
      // 选择日期
      this._chooseDates(startMonth, endMonth);
    },
    /**
     * @desc   : 选择日期
     * @author : 周兴
     * @date   : 2023/7/10 17:13
     */
    _chooseDates(startMonth, endMonth) {
      this.chooseMonths = []
      this.chooseMonths.push({
        yearMonth: startMonth.yearMonth,
        month: startMonth.month,
        year: startMonth.year,
        date: startMonth.date,
      })
      this.chooseMonths.push({
        yearMonth: endMonth.yearMonth,
        month: endMonth.month,
        year: endMonth.year,
        date: endMonth.date,
      })
      this.$nextTick(() => {
        this.visible = false;
        // 处理值的显示
        this.handleDisplayText(this.chooseMonths);
        // 恢复月份数据源的值
        this.restoreMonthData();
        if (startMonth.date < endMonth.date) {
          let betweenMonths = {
            min: startMonth.date,
            max: endMonth.date
          }
          // 设置之间的月份
          this.setBetweenMonth(betweenMonths);
        }
      })
      this.$emit('on-change',this.model.split(this.separator) )
    },
    /**
     * @desc   : 点击月份
     * @author : 周兴
     * @date   : 2023/7/7 14:52
     */
    handleClickMonth(item, year) {
      this.clickFlag = true;
      if (this.chooseMonths.length === 0) {
        // 如果点上月份，清空已选
        this.choosedMonths = []
        // 清除掉value 和text之外的数据
        this.monthData = this.monthData.map(m => {
          return {
            value: m.value,
            text: m.text
          }
        })
      }
      let yearMonth = year + '-' + item.value;
      // let filters = this.chooseMonths.filter(it => it.yearMonth === yearMonth);
      // if (!filters || filters.length === 0) {
      if (this.chooseMonths.length === 2) {
        // 如果到两个了清空
        this.chooseMonths = []
      }
      this.chooseMonths.push({
        yearMonth: yearMonth,
        month: item.value,
        year: year,
        date: new Date(year, item.value - 1, 1)
      })
      // }
      // 如果是两个月份，就隐藏pop，确定选中数据
      if (this.chooseMonths.length === 2) {
        // 按照日期开始进行排序
        this.chooseMonths = this.chooseMonths.sort((a, b) => a.date - b.date);
        this.visible = false;
        // 处理值的显示
        this.handleDisplayText(this.chooseMonths);
        this.$emit('on-change',this.model.split(this.separator) )
      }
      setTimeout(() => {
        this.clickFlag = false
      }, 1000)
    },
    /**
     * @desc   : 显示
     * @author : 周兴
     * @date   : 2023/7/7 15:19
     */
    handleDisplayText(chooseMonths) {
      let text = ''
      let date1 = new Date(chooseMonths[0].yearMonth + '-1')
      let date2 = new Date(chooseMonths[1].yearMonth + '-1')
      if (date1 < date2) {
        text = date1.toYearMonth2() + this.separator + date2.toYearMonth2()
      } else {
        text = date2.toYearMonth2() + this.separator + date1.toYearMonth2()
      }
      // 赋值给已选
      this.choosedMonths = this.chooseMonths.copy();
      // 清空当前
      this.chooseMonths = []
      this.model = text;
      this.rightModel =
        this.rightModel = {
          model: text,
          choosedMonths: this.choosedMonths?.copy()
        }
    },
    /**
     * @desc   : 处理数据
     * @author : 周兴
     * @date   : 2023/7/11 9:44
     */
    handleValue(value) {
      if (value) {
        // 数组
        if (Array.isArray(value)) {
          this.model = value.join(this.separator)
        } else {
          this.model = value;
        }
        // 处理字符串数据
        this.chooseDatas();
      }
    },
  },
  created() {
    let date = new Date();
    this.thisMonth = date.getFullYear() + '-' + (date.getMonth() + 1)
    this.startYear = date.getFullYear();
    this.endYear = this.startYear + 1;
    if (this.placeholder) {
      this.placeholderData = this.placeholder;
    } else {
      this.placeholderData = this.$t('inputWords', {'search-name': this.dkFormItem.label ? this.dkFormItem.label : this.$t(this.prop)})
    }
    // 处理数据
    this.handleValue(this.value);
  }
}
</script>

<style scoped>
.month-class {
  width: 524px;
  height: 258px;
  display: flex;
  overflow: hidden;
}

.month-left-class {
  width: 92px;
  height: 100%;
  background: #F8F8F9;
  border-right: 1px solid #E8EAEC;
  padding-top: 5px;
  padding-bottom: 5px;
}

.month-left-item-class {
  padding: 8px 15px;
  cursor: pointer;
}

.month-content {
  width: calc(100% - 92px);
  height: 100%;
}

.month-total-class {
  width: 100%;
  height: calc(100% - 40px);
  display: flex;
}


.month-title-class {
  width: 100%;
  height: 40px;
  border-bottom: 1px solid #E8EAEC;
  display: flex;
}

.month-item-class {
  width: 50%;
  height: 100%;
}

/deep/ .Row {
  padding: 14px 10px 10px 10px !important;
  margin: 0 !important;
  display: flex !important;
  align-items: center;
}

/deep/ .Col {
  padding: 10px 12px !important;
  margin: 10px 0 !important;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 28px;
}

.btn-class {
  width: 40px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.month-title-item-class {
  width: 50%;
  height: 100%;
  display: flex;
  justify-content: space-between;
}

.item-year-start-class {
  display: flex;
  align-items: center;
  margin-right: 80px;
}

.item-arrow-start-class {
  font-size: 18px;
  cursor: pointer;
  display: flex;
  align-items: center;
  margin-left: 20px;
}

.item-arrow-start-class:hover {
  color: #1e83e9;
}

.item-year-end-class {
  display: flex;
  align-items: center;
  margin-left: 80px;
}

.item-arrow-end-class {
  font-size: 18px;
  cursor: pointer;
  display: flex;
  align-items: center;
  margin-right: 20px;
}

.item-arrow-end-class:hover {
  color: #1e83e9;
}

.btn-class-between {
  background-color: #DCF0FE;
}

/deep/ .ivu-btn-default {
  border: none;
}

/deep/ .ivu-btn-default:hover {
  border: none;
  background-color: #DCF0FE;
}

/deep/ .ivu-btn-default:focus {
  border: none;
  box-shadow: none;
}

/deep/ .ivu-input {
  height: 28px;
}

/deep/ .ivu-poptip-rel {
  width: calc(100% - 16px);
}

.month-popper-class {
  width: 100%;
}


.calendar-class {
  font-size: 13px;
  position: absolute;
  top: 6px;
  right: 10px;
  z-index: 20;
}

</style>
