<!--
 * @Description: 
 * @Autor: Heloise
 * @Date: 2022-06-07 16:59:52
 * @LastEditors: Heloise
 * @LastEditTime: 2022-08-18 10:05:46
-->
<template>
  <div class="el-complex-time-popover">
    <el-popover
      ref="popoverRef"
      popper-class="el-complex-time-popover__popover"
      placement="bottom"
      width="324"
      trigger="click"
      :disabled="disabled"
    >
      <div
        slot="reference"
        class="el-complex-time-popover__tabs"
        :class="errorShow ? 'is-error' : ''"
      >
        <el-input
          readonly
          :disabled="disabled"
          placeholder="请选择"
          @focus="handleFocus"
          @blur="handleBlur"
          @clear="clear"
          @mouseenter.native="hovering = true"
          @mouseleave.native="hovering = false"
        >
          <i
            v-if="showClear"
            class="el-input__icon bi-iconfont-close-circle-fill"
            slot="suffix"
            @click.stop="clear"
          ></i>
          <i
            v-else
            class="el-input__icon bi-iconfont-calendar"
            slot="suffix"
          ></i>
        </el-input>
        <div
          :class="[
            'el-complex-time-popover__tags',
            { 'is-disabled': disabled },
          ]"
          v-if="showTabsList.length > 0"
        >
          <span>
            {{ showTabsList[0] }}
          </span>
          <span
            v-if="showTabsList.length > 1"
            class="el-complex-time-popover__tags-icon"
            >+ {{ showTabsList.length - 1 }}</span
          >
        </div>
      </div>
      <div class="el-complex-time-popover__content">
        <div class="el-complex-time-popover__content--top">
          {{
            btnKey === "fixedTime"
              ? `日期选择（去重后/${relation === 2 ? "且" : "或"}关系）：${
                  showTabsList[0] ? "" : "-"
                }`
              : `日期选择：${showTabsList[0] ? showTabsList[0] : "-"}`
          }}
          <div v-if="btnKey === 'fixedTime'" class="complex-top-text">
            <div v-for="(item, index) in showTabsList" :key="index">
              <span v-show="index !== 0">
                {{ relation === 2 ? "且" : "或" }} </span
              >{{ item }}
            </div>
          </div>
        </div>
        <div class="el-complex-time-popover__content--bottom">
          <div class="complex-btns-class">
            <span
              :class="[
                'complex-btns-span',
                { 'is-selected': btnKey === item.key },
                { 'is-disabled': item.disabled },
              ]"
              v-for="(item, index) in btnList"
              @click="btnsTypeClick(item.key)"
              :value="item.key"
              :key="index"
            >
              <span>{{ item.chooseTag }}</span>
              <el-tooltip
                v-if="item.text"
                :content="item.text"
                placement="bottom"
              >
                <i class="bi-iconfont-help"></i>
              </el-tooltip>
            </span>
          </div>
          <div class="complex-btns-content">
            <div
              v-if="btnKey === 'fixedTime'"
              class="complex-btns-content-fixed"
            >
              <el-form
                :model="fixedForm"
                ref="fixedForm"
                class="complex-btns-content-fixed__form-dynamic"
              >
                <el-form-item
                  v-for="(item, index) in fixedForm.items"
                  :key="`${index}${item.key ? item.key : ''}`"
                  :prop="'items.' + index + '.value'"
                >
                  <el-date-picker
                    v-model="item.value"
                    v-bind="$attrs"
                    type="daterange"
                    range-separator="至"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    format="yyyy/MM/dd"
                    value-format="yyyy/MM/dd"
                    @change="fixedChange"
                  >
                  </el-date-picker>
                  <i
                    class="bi-iconfont-close"
                    v-if="fixedForm.items.length > 1"
                    @click="handleRemove(item)"
                  ></i>
                </el-form-item>
                <el-form-item>
                  <el-button
                    type="dashed"
                    icon="bi-iconfont-add"
                    @click="handleAdd"
                    >添加日期段</el-button
                  >
                </el-form-item>
              </el-form>
            </div>
            <div
              v-if="btnKey === 'dynamicTime'"
              class="complex-btns-content-dynamic"
            >
              <el-radio-group v-model="dynamicRadio">
                <el-radio-button :label="0" @click.native="dynamicTabClick()"
                  >具体日期段</el-radio-button
                >
                <el-radio-button :label="1" @click.native="dynamicTabClick()"
                  >过去N（天/月/年）</el-radio-button
                >
              </el-radio-group>
              <el-form :model="dynamicForm" ref="dynamicForm">
                <el-form-item
                  v-if="dynamicRadio === 0"
                  key="dynamicDate"
                  prop="dynamicDate"
                >
                  <el-date-picker
                    v-model="dynamicForm.dynamicDate"
                    v-bind="$attrs"
                    type="daterange"
                    range-separator="至"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    format="yyyy/MM/dd"
                    value-format="yyyy/MM/dd"
                    @change="dynamicChange"
                  ></el-date-picker>
                </el-form-item>
                <div v-else>
                  <el-form-item key="dynamicNum" prop="dynamicNum">
                    <el-input-number
                      v-model="dynamicForm.dynamicNum"
                      controls-position="right"
                      placeholder="请输入"
                      @change="handleChange"
                      :min="1"
                      :step="1"
                      :precision="0"
                    ></el-input-number>
                  </el-form-item>
                  <el-form-item key="dynamicSelect" prop="dynamicSelect">
                    <el-select
                      v-model="dynamicForm.dynamicSelect"
                      @change="handleChange"
                    >
                      <el-option
                        v-for="item in optionList"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                      >
                      </el-option>
                    </el-select>
                  </el-form-item>
                </div>
              </el-form>
            </div>
          </div>
        </div>
      </div>
    </el-popover>
    <div v-if="errorShow" class="el-complex-time-popover__error-tip">
      {{ errorTxt }}
    </div>
  </div>
</template>

<script>
import fecha from 'bi-element/src/utils/date';
import moment from 'moment';

export default {
  name: 'ElComplexTimePopover',
  props: {
    required: {
      type: Boolean,
      default: false
    },
    clearable: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    relation: {
      type: Number,
      default: 1
    },
    value: Object,
    errorTxt: {
      type: String,
      default: '请选择'
    },
    optionList: {
      type: Array,
      default: () => [
        {
          value: 'day',
          label: '天'
        },
        {
          value: 'month',
          label: '月'
        },
        {
          value: 'year',
          label: '年'
        }
      ]
    },
    btnList: {
      type: Array,
      default: () => [
        { key: 'today', chooseTag: '今日', disabled: false },
        { key: 'yesterday', chooseTag: '昨日' },
        { key: 'thisWeek', chooseTag: '本周' },
        { key: 'lastWeek', chooseTag: '上周' },
        { key: 'thisMonth', chooseTag: '本月' },
        { key: 'lastMonth', chooseTag: '上月' },
        { key: 'thisYear', chooseTag: '本年', disabled: false },
        { key: 'lastYear', chooseTag: '去年', disabled: false },
        {
          key: 'fixedTime',
          chooseTag: '固定日期',
          text: '设置固定日期则认为在此日期内有效，超出日期无效'
        },
        {
          key: 'dynamicTime',
          chooseTag: '动态日期',
          text: '动态日期为一段时间的日期窗口，会跟随时间的变化进行推移计算'
        }
      ]
    }
  },
  data() {
    return {
      hovering: false,
      focused: false,
      errorShow: false,
      btnKey: 'fixedTime',
      complexValue: {},
      showTabsList: [],
      dynamicRadio: 0,
      dynamicForm: {
        dynamicDate: [],
        dynamicNum: undefined,
        dynamicSelect: ''
      },
      dynamicDateList: [], // 动态日期（转过去xxx天数组传给后台）
      fixedFormList: [], // 固定日期（转时间戳传给后台）
      fixedForm: {
        items: [
          {
            value: []
          }
        ]
      }
    };
  },
  computed: {
    showClear() {
      return (
        this.clearable &&
        !this.disabled &&
        (this.focused || this.hovering) &&
        this.showTabsList.length > 0
      );
    }
  },
  watch: {
    complexValue: {
      handler(newVal) {
        this.$emit('getComplexValue', newVal);
      },
      deep: true
    },
    showTabsList: {
      handler(newVal) {
        if (newVal.length) {
          this.errorShow = false;
        }
      },
      deep: true
    },
    btnKey(newVal, oldVal) {
      if (oldVal === 'fixedTime') {
        this.fixedFormList = [];
        this.fixedForm = {
          items: [
            {
              value: []
            }
          ]
        };
      } else if (oldVal === 'dynamicTime') {
        this.dynamicRadio = 0;
        this.dynamicDateList = [];
        this.$refs['dynamicForm'].resetFields();
      }
    }
  },
  created() {
    this.echoData(this.value);
  },
  mounted() {
    this.$watch(
      '$refs.popoverRef.showPopper',
      (newVal, oldVal) => {
        this.handleVertify(false, newVal, oldVal);
      },
      {
        immediate: true
      }
    );
  },
  methods: {
    echoData(echoVal) {
      if (
        Object.prototype.toString.call(echoVal) === '[object Object]' &&
        echoVal.key
      ) {
        this.btnsTypeClick(echoVal.key);
        if (echoVal.key === 'fixedTime') {
          // 固定日期：{key: "fixedTime", value: [[1630425600000, 1630771200000], [1631030400000, 1634486400000]]}
          if (echoVal.value.length > 0) {
            let itemsArr = [];
            for (let iterator of echoVal.value) {
              let obj = {};
              let arr = [];
              arr[0] = fecha.format(
                new Date(parseInt(iterator[0], 10)),
                'yyyy/MM/dd'
              );
              arr[1] = fecha.format(
                new Date(parseInt(iterator[1], 10)),
                'yyyy/MM/dd'
              );
              obj.value = arr;
              itemsArr.push(obj);
            }
            this.fixedForm.items = itemsArr;
            this.fixedChange();
          } else {
            this.fixedForm = {
              items: [
                {
                  value: []
                }
              ]
            };
          }
        } else if (echoVal.key === 'dynamicTime') {
          // 动态日期-具体时间段：{key: "dynamicTime", value: [-15, 14]}；
          // 动态日期-过去N（天/月/年）：{key: "dynamicTime", value: [2, "year"]}
          if (echoVal.value.length > 0) {
            if (
              typeof echoVal.value[1] === 'number' &&
              !isNaN(echoVal.value[1])
            ) {
              // 第二个值是数字-具体时间段
              let arr = [];
              let now = fecha.format(new Date());
              this.$nextTick(() => {
                arr[0] = moment(now)
                  .add(echoVal.value[0], 'days')
                  .format('YYYY/MM/DD');
                arr[1] = moment(now)
                  .add(echoVal.value[1], 'days')
                  .format('YYYY/MM/DD');
                this.dynamicForm.dynamicDate = arr;
                this.dynamicChange(arr);
              });
            } else {
              this.dynamicRadio = 1;
              this.$nextTick(() => {
                this.dynamicForm = {
                  dynamicDate: [],
                  dynamicNum: echoVal.value[0],
                  dynamicSelect: echoVal.value[1]
                };
                this.handleChange();
              });
            }
          } else {
            this.dynamicForm = {
              dynamicDate: [],
              dynamicNum: undefined,
              dynamicSelect: ''
            };
          }
        }
      }
    },
    /**
     * @description: 校验
     * @param {*} flag
     * @param {*} newVal
     * @param {*} oldVal
     * @return {*}
     */
    handleVertify(flag = true, newVal, oldVal) {
      if (this.required) {
        if (
          (flag || (oldVal && !newVal && !this.disabled)) &&
          this.showTabsList.length <= 0
        ) {
          this.errorShow = true;
        }
      } else {
        this.errorShow = false;
      }
    },
    handleReset() {
      this.complexValue = {};
      this.showTabsList = [];
      this.btnKey = 'fixedTime';
      this.fixedFormList = [];
      this.fixedForm = {
        items: [
          {
            value: []
          }
        ]
      };
      this.errorShow = false;
    },
    handleFocus() {
      this.focused = true;
    },
    handleBlur() {
      this.focused = false;
    },
    /**
     * @description: 清空
     * @return {*}
     */
    clear() {
      this.handleReset();
      if (this.required) {
        this.errorShow = true;
      }
    },
    btnsTypeClick(key) {
      if (this.btnKey !== key) {
        this.btnKey = key;
        this.showTabsList = [];
      }
      if (key !== 'fixedTime' && key !== 'dynamicTime') {
        this.complexValue = { key: this.btnKey };
        this.$refs.popoverRef && this.$refs.popoverRef.doClose();
      } else {
        this.complexValue = { key: this.btnKey, value: [] };
      }
      switch (this.btnKey) {
        case 'today':
          this.showTabsList[0] = fecha.format(new Date(), 'yyyy/MM/dd');
          break;
        case 'yesterday':
          const date = new Date();
          date.setTime(date.getTime() - 3600 * 1000 * 24);
          this.showTabsList[0] = fecha.format(date, 'yyyy/MM/dd');
          break;
        case 'thisWeek':
          const start = new Date();
          const end = new Date();
          const nows = start.getDay() || 7;
          start.setTime(start.getTime() - 3600 * 1000 * 24 * (nows - 1));
          this.showTabsList[0] =
            fecha.format(start, 'yyyy/MM/dd') +
            ' - ' +
            fecha.format(end, 'yyyy/MM/dd');
          break;
        case 'lastWeek':
          const dataValue = new Date();
          const year = dataValue.getFullYear();
          const month = dataValue.getMonth() + 1;
          const day = dataValue.getDate();
          var thisWeekStart; // 本周周一的时间
          if (dataValue.getDay() === 0) {
            // 周天的情况；
            thisWeekStart =
              new Date(year + '/' + month + '/' + day).getTime() -
              (dataValue.getDay() + 6) * 86400000;
          } else {
            thisWeekStart =
              new Date(year + '/' + month + '/' + day).getTime() -
              (dataValue.getDay() - 1) * 86400000;
          }
          const prevWeekStart = thisWeekStart - 7 * 86400000; // 上周周一的时间
          const prevWeekEnd = thisWeekStart - 1 * 86400000; // 上周周日的时间
          const lastWeekStart = new Date(prevWeekStart); // 开始时间
          const lastWeekEnd = new Date(prevWeekEnd); // 结束时间
          this.showTabsList[0] =
            fecha.format(lastWeekStart, 'yyyy/MM/dd') +
            ' - ' +
            fecha.format(lastWeekEnd, 'yyyy/MM/dd');
          break;
        case 'thisMonth':
          const thisMonthEnd = new Date();
          const thisMonthStart = new Date();
          thisMonthStart.setDate(1);
          this.showTabsList[0] =
            fecha.format(thisMonthStart, 'yyyy/MM/dd') +
            ' - ' +
            fecha.format(thisMonthEnd, 'yyyy/MM/dd');
          break;
        case 'lastMonth':
          const lastMonthStart = new Date();
          const lastMonthEnd = new Date(lastMonthStart);
          lastMonthEnd.setMonth(lastMonthStart.getMonth());
          lastMonthStart.setMonth(lastMonthStart.getMonth() - 1);
          lastMonthEnd.setDate(0);
          lastMonthStart.setDate(1);
          this.showTabsList[0] =
            fecha.format(lastMonthStart, 'yyyy/MM/dd') +
            ' - ' +
            fecha.format(lastMonthEnd, 'yyyy/MM/dd');
          break;
        case 'thisYear':
          const thisYearEnd = new Date();
          const thisYearStart = new Date();
          thisYearStart.setDate(1);
          thisYearStart.setMonth(0);
          this.showTabsList[0] =
            fecha.format(thisYearStart, 'yyyy/MM/dd') +
            ' - ' +
            fecha.format(thisYearEnd, 'yyyy/MM/dd');
          break;
        case 'lastYear':
          const lastYearStart = new Date();
          const lastYearEnd = new Date();
          lastYearStart.setFullYear(lastYearStart.getFullYear() - 1);
          lastYearStart.setDate(1);
          lastYearStart.setMonth(0);
          lastYearEnd.setFullYear(lastYearStart.getFullYear());
          lastYearEnd.setDate(0);
          lastYearEnd.setMonth(11);
          this.showTabsList[0] =
            fecha.format(lastYearStart, 'yyyy/MM/dd') +
            ' - ' +
            fecha.format(lastYearEnd, 'yyyy/MM/dd');
          break;
        default:
          return '未匹配到合适的弹窗！';
      }
    },

    // 固定日期
    handleAdd() {
      this.fixedForm.items.push({
        value: '',
        key: Date.now()
      });
    },
    handleRemove(item) {
      var index = this.fixedForm.items.indexOf(item);
      if (index !== -1) {
        this.fixedForm.items.splice(index, 1);
      }
      // this.$refs.popoverRef.updatePopper();
      this.fixedChange();
    },
    /**
     * @description: 判断一组数字是否连续
     * @param {*} arr
     * @return {*}
     */
    continuous(arr) {
      var t;
      var ta;
      var r = [];
      arr.forEach((v) => {
        if (t === v) {
          ta.push(t);
          t++;
          return;
        }
        ta = [v];
        t = v + 1;
        r.push(ta);
      });
      return r;
    },
    /**
     * @description: 转换时间戳并去重数据
     * @param {*}
     * @return {*}
     */
    fixedChange() {
      let arr = [];
      let now = fecha.format(new Date(), 'yyyy/MM/dd');
      for (let iterator of this.fixedForm.items) {
        let e = iterator.value;
        if (e && e.length > 0 && e[0]) {
          let one = moment(e[0]).diff(moment(now), 'days');
          let two = moment(e[1]).diff(moment(now), 'days');
          let temp = one;
          while (temp <= two) {
            arr.push(temp);
            temp++;
          }
        }
      }
      let tempArr = Array.from(new Set(arr));
      // 排序
      tempArr = tempArr.sort((a, b) => {
        return a - b;
      });
      // console.log(this.continuous(tempArr))
      // 去重之后的时间段数组（距离多少天）
      let continuousArr = this.continuous(tempArr);
      let showTabsArr = [];
      let tempList = [];
      for (let continuousItem of continuousArr) {
        let str = '';
        let start = moment(now)
          .add(continuousItem[0], 'days')
          .format('YYYY/MM/DD');
        let end = moment(now)
          .add(continuousItem[continuousItem.length - 1], 'days')
          .format('YYYY/MM/DD');
        str = start + ' - ' + end;
        showTabsArr.push(str);
        let tempArr = [];
        tempArr[0] = new Date(start).getTime();
        tempArr[1] = new Date(end).getTime();
        tempList.push(tempArr);
      }
      this.fixedFormList = tempList;
      this.showTabsList = showTabsArr;
      this.complexValue = {
        key: this.btnKey,
        value: this.fixedFormList
      };
    },

    // 动态日期
    /**
     * @description: 动态时间-具体时间
     * @param {*} e
     * @return {*}
     */
    dynamicChange(e) {
      if (e && e.length > 0 && e[0]) {
        this.showTabsList = [e[0] + ' - ' + e[1]];
        let now = fecha.format(new Date());
        this.dynamicDateList[0] = moment(e[0]).diff(moment(now), 'days');
        this.dynamicDateList[1] = moment(e[1]).diff(moment(now), 'days');
        this.complexValue = {
          key: this.btnKey,
          value: this.dynamicDateList // 具体时间、以当天（0）为基准
        };
      } else {
        this.complexValue = {
          key: this.btnKey,
          value: []
        };
        this.showTabsList = [];
      }
    },
    dynamicTabClick() {
      let oldRadio = JSON.parse(JSON.stringify(this.dynamicRadio));
      this.$nextTick(() => {
        if (oldRadio !== this.dynamicRadio) {
          this.$refs['dynamicForm'].resetFields();
          this.dynamicDateList = [];
          this.showTabsList = [];
          this.complexValue = {
            key: 'dynamicTime',
            value: []
          };
        }
      });
    },
    /**
     * @description: 动态时间-过去N（天/月/年）
     * @param {*}
     * @return {*}
     */
    handleChange() {
      let num = this.dynamicForm.dynamicNum;
      let e = this.dynamicForm.dynamicSelect;
      let now = fecha.format(new Date());
      if (num && e) {
        let start = '';
        let end = moment(now).subtract(1, 'days').format('YYYY/MM/DD');
        if (e === 'day') {
          start = moment(now).subtract(num, 'days').format('YYYY/MM/DD');
          this.showTabsList[0] = start + ' - ' + end;
        } else if (e === 'month') {
          start = moment(now)
            .subtract(num, 'months')
            .subtract(1, 'days')
            .format('YYYY/MM/DD');
          this.showTabsList[0] = start + ' - ' + end;
        } else if (e === 'year') {
          start = moment(now)
            .subtract(num, 'years')
            .subtract(1, 'days')
            .format('YYYY/MM/DD');
          this.showTabsList[0] = start + ' - ' + end;
        }
        let arr = [num, e];
        this.complexValue = { key: this.btnKey, value: arr };
        this.errorShow = false;
      } else {
        if (!num) {
          this.dynamicTabClick();
        }
      }
    }
  }
};
</script>
