<template>
  <view class="cv-picker">
    <picker
      class="cv-picker-item"
      mode="multiSelector"
      :range="range_data"
      :value="items_index"
      @change="bindPickerChange"
      @columnchange="bindPickerColumnchange"
      @cancel="onCancel"
      @click="changeIconTop"
    >
      <view class="cv-picker-item-text" v-if="localVal">
        {{ localVal }}
      </view>
      <view class="cv-picker-item-placeholder" v-else>{{ placeholder }}</view>
    </picker>
  </view>
</template>
<script>
import mpMixin from '../../libs/mixin/mpMixin.js';
import mixin from '../../libs/mixin/mixin.js';
export default {
  mixins: [mpMixin, mixin],
  name: 'cvDatetimeLinkage',
  emits: ['input', 'update:modelValue'],
  props: {
    //默认输入框内容
    value: {
      type: String,
      default: ''
    },
    modelValue: {
      type: String,
      default: ''
    },
    dataType: {
      type: String,
      default: 'text'
    },
    joint: {
      type: String,
      default: '-'
    },
    start: {
      type: String,
      default: ''
    },
    end: {
      type: String,
      default: ''
    },
    // 占位符
    placeholder: {
      type: String,
      default: '请选择'
    }
  },
  watch: {
    value(newVal) {
      this.localVal = newVal;
      this.itemsSortOut();
    },
    modelValue(newVal) {
      this.localVal = newVal;
      this.itemsSortOut();
    }
  },
  data() {
    return {
      iconTop: false,
      localVal: '',
      localJoint: '',
      range_data: [], //弹窗临时数组
      last_range_data: [], //最终显示页面数组
      items_index: [0, 0, 0, 0, 0], //当前下标
      lastRetDataIndex: [0, 0, 0, 0, 0], // 最终确定选中的下标
      localDataType: 'text',
      dataValue: 'value',
      dataText: 'label',
      newDate: new Date(),
      localDatetimeArr: [], //临时日期时间数组
      lastDatetimeArr: [], //选中日期时间数组
      startDatetimeArr: [], //开始日期时间数组
      endDatetimeArr: [] //结束日期时间数组
    };
  },
  created() {
    this.localVal = this.doValueGet();
    this.localDataType = this.dataType != 'value' ? 'text' : 'value';
    this.localJoint = this.joint;

    this.startDatetimeArr = this._splitDatetime(this.start);
    this.endDatetimeArr = this._getEndDatetime(this.end);

    this.itemsSortOut();
  },
  methods: {
    doValueGet() {
      if (this.value === '') return this.modelValue;
      if (this.modelValue === '') return this.value;
      return this.value;
    },
    initReginData(data) {
      let localData = [];
      for (const key in data) {
        localData.push({
          text: data[key],
          value: key
        });
      }
      return localData;
    },
    itemsSortOut() {
      let localDatetimeArr = [],
        lastDatetimeArr = [];
      /* 获取当前日期的默认事件 */
      if (this.localVal) {
        //空格拆分日期和时间
        lastDatetimeArr = this._splitDatetime(this.localVal, true);
        localDatetimeArr = [...lastDatetimeArr];
      } else {
        localDatetimeArr = [
          this._convert_two_digits(this.newDate.getFullYear()),
          this._convert_two_digits(this.newDate.getMonth() + 1),
          this._convert_two_digits(this.newDate.getDate()),
          this._convert_two_digits(this.newDate.getHours()),
          this._convert_two_digits(this.newDate.getMinutes())
        ];
      }
      this.localDatetimeArr = localDatetimeArr;
      this.lastDatetimeArr = lastDatetimeArr;
      //初始化年份列表
      this.range_data[0] = this._getYear();
      //获取临时年份的id
      this.items_index[0] = this._getKey(this.range_data[0], localDatetimeArr[0]);
      //获取选中年份的id
      this.lastRetDataIndex[0] = this._getKey(this.range_data[0], lastDatetimeArr[0]);
      //初始化月份
      this.range_data[1] = this._getMonth();
      //获取临时月份的id
      this.items_index[1] = this._getKey(this.range_data[1], localDatetimeArr[1]);
      //获取选中月份的id
      this.lastRetDataIndex[1] = this._getKey(this.range_data[1], lastDatetimeArr[1]);
      //初始化日
      this.range_data[2] = this._getDate(localDatetimeArr[1], localDatetimeArr[0]);
      //获取临时日的id
      this.items_index[2] = this._getKey(this.range_data[2], localDatetimeArr[2]);
      //获取选中日的id
      this.lastRetDataIndex[2] = this._getKey(this.range_data[2], lastDatetimeArr[2]);

      //初始化小时
      this.range_data[3] = this._getHours();
      //获取临时小时的id
      this.items_index[3] = this._getKey(this.range_data[3], localDatetimeArr[3]);
      //获取选中小时的id
      this.lastRetDataIndex[3] = this._getKey(this.range_data[3], lastDatetimeArr[3]);

      //初始化分钟
      this.range_data[4] = this._getMinutes();
      //获取临时小时的id
      this.items_index[4] = this._getKey(this.range_data[4], localDatetimeArr[4]);
      //获取选中小时的id
      this.lastRetDataIndex[4] = this._getKey(this.range_data[4], lastDatetimeArr[4]);

      this.lastDatetimeArr = [...lastDatetimeArr];
      this.localDatetimeArr = [...localDatetimeArr];
      this.last_range_data = [...this.range_data];
    },
    /* 拆分时日期时间为数组 */
    _splitDatetime(datetime, join = false) {
      let data = [];
      if (!datetime) {
        return data;
      }
      let datetimeArr = datetime.split(' ');
      let date = datetimeArr[0];
      let time = datetimeArr[1];

      //分割日期
      let dateArr = date.split('-');
      let localJoint = '-';
      if (dateArr.length <= 1) {
        dateArr = date.split('/');
        if (join) {
          this.localJoint = '/';
        }
      }
      data[0] = this._convert_two_digits(dateArr[0]);
      data[1] = this._convert_two_digits(dateArr[1]);
      data[2] = this._convert_two_digits(dateArr[2]);
      if (!time) {
        return data;
      }

      //分割时间
      let timeArr = time.split(':');
      data[3] = this._convert_two_digits(timeArr[0]);
      data[4] = this._convert_two_digits(timeArr[1]);

      return data;
    },
    //获取结束时间
    _getEndDatetime(data) {
      let endDatetimeArr = this._splitDatetime(data);
      let startDatetimeArr = [...this.startDatetimeArr];
      //判断结束时间是否合法   若：结束时间大于开始时间，则：无效
      if (endDatetimeArr.length <= 0 || startDatetimeArr.length <= 0) {
        return endDatetimeArr;
      }
      //年份较小 结束时间无效
      if (endDatetimeArr[0] < startDatetimeArr[0]) {
        console.warn('//年份较小 结束时间无效');
        return [];
      }
      //年份较大着时间必定会大
      if (endDatetimeArr[0] > startDatetimeArr[0]) {
        return endDatetimeArr;
      }

      /* 年份相同比较月份 */
      //月份较小 结束时间无效
      if (endDatetimeArr[1] < startDatetimeArr[1]) {
        console.warn('//月份较小 结束时间无效');
        return [];
      }
      //月份较大着时间必定会大
      if (endDatetimeArr[1] > startDatetimeArr[1]) {
        return endDatetimeArr;
      }

      /* 年份月份相同比较日 */
      //日较小 结束时间无效
      if (endDatetimeArr[2] < startDatetimeArr[2]) {
        console.warn('//日较小 结束时间无效');
        return [];
      }
      //日较大着时间必定会大
      if (endDatetimeArr[2] > startDatetimeArr[2]) {
        return endDatetimeArr;
      }

      /* 年份、月份及日相同比较时 */
      //日较小 结束时间无效
      if (endDatetimeArr[3] < startDatetimeArr[3]) {
        console.warn('//时较小 结束时间无效');
        return [];
      }
      //日较大着时间必定会大
      if (endDatetimeArr[3] > startDatetimeArr[3]) {
        return endDatetimeArr;
      }

      /* 年份、月份、日及时相同比较分 */
      //分较小 结束时间无效
      if (endDatetimeArr[4] < startDatetimeArr[4]) {
        console.warn('//时较小 结束时间无效');
        return [];
      }
      //分较大着时间必定会大
      if (endDatetimeArr[4] > startDatetimeArr[4]) {
        return endDatetimeArr;
      }
      return endDatetimeArr;
    },
    /* 获取年份 */
    _getYear() {
      let localData = [];
      //开始年
      let startYear = this.startDatetimeArr[0] || 1970;
      //结束年
      let endYear = this.endDatetimeArr[0] || this.newDate.getFullYear() + 50;
      for (let i = startYear; i <= endYear; ++i) {
        localData.push(i + '年');
      }
      return localData;
    },
    /* 获取月份 */
    _getMonth() {
      let localData = [];
      //开始月
      let startMonth = 1;
      if (this.startDatetimeArr[0] == this.localDatetimeArr[0]) {
        startMonth = this.startDatetimeArr[1];
      }
      //结束月
      let endMonth = 12;
      if (this.localDatetimeArr[0] == this.endDatetimeArr[0]) {
        endMonth = this.endDatetimeArr[1];
      }
      for (let i = startMonth; i <= endMonth; ++i) {
        localData.push(this._convert_two_digits(i) + '月');
      }
      return localData;
    },
    /* 获取日期 */
    _getDate(month, year) {
      let localData = [];
      let days = 0;
      let endday =
        this.endDatetimeArr[0] == this.localDatetimeArr[0] && this.endDatetimeArr[1] == this.localDatetimeArr[1]
          ? this.startDatetimeArr[2]
          : 0;
      let startDay =
        this.startDatetimeArr[0] == this.localDatetimeArr[0] && this.startDatetimeArr[1] == this.localDatetimeArr[1]
          ? this.startDatetimeArr[2]
          : 1;
      if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 || month == '') {
        days = 31;
      } else if (month == 4 || month == 6 || month == 9 || month == 11) {
        days = 30;
      } else {
        //二月算法
        //世纪闰年 || 普通闰年
        if ((year % 100 == 0 && year % 400 == 0) || (year % 100 !== 0 && year % 4 == 0)) {
          days = 29;
        } else {
          days = 28;
        }
      }
      if (endday > days || endday == 0) {
        endday = days;
      }
      for (let i = startDay; i <= endday; ++i) {
        localData.push(this._convert_two_digits(i) + '日');
      }
      return localData;
    },
    /* 获取小时 */
    _getHours() {
      let localData = [];
      let start =
        this.startDatetimeArr[0] == this.localDatetimeArr[0] &&
        this.startDatetimeArr[1] == this.localDatetimeArr[1] &&
        this.startDatetimeArr[2] == this.localDatetimeArr[2]
          ? this.startDatetimeArr[3]
          : 1;
      let end =
        this.endDatetimeArr[0] == this.localDatetimeArr[0] &&
        this.endDatetimeArr[1] == this.localDatetimeArr[1] &&
        this.endDatetimeArr[2] == this.localDatetimeArr[2]
          ? this.endDatetimeArr[3]
          : 23;
      for (let i = start; i <= end; ++i) {
        localData.push(this._convert_two_digits(i) + '时');
      }
      return localData;
    },
    _getMinutes() {
      let localData = [];
      let start =
        this.startDatetimeArr[0] == this.localDatetimeArr[0] &&
        this.startDatetimeArr[1] == this.localDatetimeArr[1] &&
        this.startDatetimeArr[2] == this.localDatetimeArr[2] &&
        this.startDatetimeArr[3] == this.localDatetimeArr[3]
          ? this.startDatetimeArr[4]
          : 1;
      let end =
        this.endDatetimeArr[0] == this.localDatetimeArr[0] &&
        this.endDatetimeArr[1] == this.localDatetimeArr[1] &&
        this.endDatetimeArr[2] == this.localDatetimeArr[2] &&
        this.endDatetimeArr[3] == this.localDatetimeArr[3]
          ? this.endDatetimeArr[4]
          : 59;
      for (let i = start; i <= end; ++i) {
        localData.push(this._convert_two_digits(i) + '分');
      }
      return localData;
    },
    /* 获取默认值的key */
    _getKey(data, localValue) {
      let localKey = 0;
      if (localValue) {
        /* 遍历数组 找出对应值的key */
        for (const key in data) {
          if (localValue == parseInt(data[key])) {
            localKey = parseInt(key);
          }
        }
      }
      return localKey;
    },
    _convert_two_digits(number) {
      if (number < 10 && parseInt(number).toString().length < 2) {
        number = '0' + parseInt(number).toString();
      } else {
        number = parseInt(number).toString();
      }
      return number;
    },
    bindPickerChange: function (e) {
      let items_index = e.detail.value;
      this.items_index = items_index;
      this.updatelocalVal();
      this.iconTop = false;
    },
    changeIconTop() {
      this.iconTop = true;
    },
    /* 取消选择 */
    onCancel(e) {
      this.iconTop = false;
      this.range_data = [...this.last_range_data];
      this.items_index = [...this.lastRetDataIndex];
    },
    bindPickerColumnchange: function (e) {
      this.items_index[e.detail.column] = e.detail.value;
      switch (e.detail.column) {
        case 0: //滑动年份
          //年份数据变动
          this.localDatetimeArr[0] = this.range_data[0][e.detail.value].replace('年', '');
          //初始化月
          //初始化日
          this.range_data[2] = this._getDate(this.localDatetimeArr[1], this.localDatetimeArr[0]);
          //初始化时
          this.range_data[3] = this._getHours();
          //初始化分
          this.range_data[4] = this._getMinutes();
          break;
        case 1: //滑动月
          //月变化
          this.localDatetimeArr[1] = this.range_data[1][e.detail.value].replace('月', '');
          //初始化日
          this.range_data[2] = this._getDate(this.localDatetimeArr[1], this.localDatetimeArr[0]);
          //初始化时
          this.range_data[3] = this._getHours();
          //初始化分
          this.range_data[4] = this._getMinutes();
          break;
        case 2: //滑动日
          //日变化
          this.localDatetimeArr[2] = this.range_data[2][e.detail.value].replace('日', '');
          //初始化时
          this.range_data[3] = this._getHours();
          //初始化分
          this.range_data[4] = this._getMinutes();
          break;
        case 3: //滑动时
          //时变化
          this.localDatetimeArr[3] = this.range_data[3][e.detail.value].replace('时', '');
          //初始化分
          this.range_data[4] = this._getMinutes();
          break;
        case 4: //滑动分
          //分变化
          this.localDatetimeArr[4] = this.range_data[4][e.detail.value].replace('分', '');
          break;
      }
    },
    updatelocalVal() {
      this.last_range_data = [...this.range_data];
      this.lastRetDataIndex = [...this.items_index];

      this.lastDatetimeArr = [...this.localDatetimeArr];
      const lastDatetimeArr = [...this.lastDatetimeArr];
      this.localVal =
        lastDatetimeArr[0] +
        this.localJoint +
        lastDatetimeArr[1] +
        this.localJoint +
        lastDatetimeArr[2] +
        ' ' +
        lastDatetimeArr[3] +
        ':' +
        lastDatetimeArr[4];
      this.$emit('input', this.localVal);
      this.$emit('update:modelValue', this.localVal);
    }
  }
};
</script>

<style>
.cv-picker {
  min-height: 35px;
  display: flex;
  flex: 1;
}
.cv-picker-item {
  height: 35px;
  line-height: 35px;
  /* display: flex;微信小程序不加这个 */

  width: 100%;
  flex-wrap: wrap;
  margin-left: 20px;
}

.cv-picker-item-placeholder {
  color: grey;
}
</style>
