<template>
  <div class="time_root">
    <table
      class="my_table"
      @mousedown="tableMousedown"
      @mousemove="tableMousemove"
      @mouseup="tableMouseup"
      @mouseleave="tableMouseleave"
    >
      <tr>
        <th class="blank"></th>
        <!-- <th colspan="4" v-for="_hour in 12" :key="_hour">
          {{
            _hour * 2 - 1 > 9 ? `${_hour * 2 - 1}:00` : `0${_hour * 2 - 1}:00`
          }}
        </th> -->
        <th colspan="2" v-for="_hour in 24" :key="_hour">
          {{ _hour > 9 ? _hour : `0${_hour}` }}
        </th>
      </tr>
      <tr v-for="(weekItem, weekIndex) in weekDay" :key="weekItem.value">
        <td>{{ weekItem.label }}</td>
        <td
          :data-time="
            JSON.stringify({
              weekValue: weekItem.value,
              weekIndex: weekIndex,
              halfHour: halfHour
            })
          "
          :class="{
            cursor_pointer: true,
            selected:
              (!tableMouseInfo.start &&
                timeInfo[weekItem.value] &&
                timeInfo[weekItem.value].includes(halfHour)) ||
              (tableMouseInfo.start &&
                tempTimeInfo[weekItem.value] &&
                tempTimeInfo[weekItem.value].includes(halfHour))
          }"
          v-for="halfHour in 48"
          :key="halfHour"
          :title="getTimeTitle(weekItem.label, halfHour)"
        ></td>
      </tr>
    </table>
    <div class="bottom_tip">
      <div class="bottom_tip_left">
        <div class="effective"></div>
        有效
        <div class="invalid"></div>
        无效
      </div>
      <div class="bottom_tip_right">每个代表30分钟</div>
    </div>
  </div>
</template>

<script>
import { weekDay } from "@/utils";
export default {
  props: {
    // 时间回显
    times: {
      type: Array,
      default() {
        return [];
      }
    }
  },
  data() {
    return {
      weekDay,
      // 时间策略信息
      timeInfo: {},
      // 临时时间策略
      tempTimeInfo: {},
      // 时间选中信息
      tableMouseInfo: {
        // 是否开始选中
        start: false,
        // 开始选中的信息
        weekValue: null,
        weekIndex: null,
        halfHour: null
      }
    };
  },
  watch: {
    times: {
      handler() {
        this.getTimeInfo();
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    getTimeInfo() {
      let _times = JSON.parse(JSON.stringify(this.times));
      let _timeInfo = {};
      for (const timeItem of _times) {
        if (!_timeInfo[timeItem.week]) {
          _timeInfo[timeItem.week] = [];
        }
        if (timeItem.stoptime === "23:59") {
          timeItem.stoptime = "24:00";
        }
        let _starttimeArr = timeItem.starttime.split(":");
        let _stoptimeArr = timeItem.stoptime.split(":");
        let _startHalfHour = Number(_starttimeArr[0]) * 2;
        if (Number(_starttimeArr[1]) === 30) {
          _startHalfHour++;
        }
        let _stopHalfHour = Number(_stoptimeArr[0]) * 2;
        if (Number(_stoptimeArr[1]) === 30) {
          _stopHalfHour++;
        }
        if (_stopHalfHour === _startHalfHour + 1) {
          _timeInfo[timeItem.week].push(_stopHalfHour);
        } else {
          while (_startHalfHour < _stopHalfHour) {
            _startHalfHour++;
            _timeInfo[timeItem.week].push(_startHalfHour);
          }
        }
      }
      this.timeInfo = _timeInfo;
    },
    // 时间变化
    timesChange() {
      let _timeInfo = this.timeInfo;
      let _times = [];
      for (const weekValue in _timeInfo) {
        let _dayHalfHours = _timeInfo[weekValue];
        if (_dayHalfHours && _dayHalfHours.length > 0) {
          _dayHalfHours = _dayHalfHours.sort((a, b) => {
            return a - b;
          });
          let _dayTimeInfo = {
            week: weekValue,
            starttime: null,
            stoptime: null,
            prevHalfHour: null
          };
          for (let index = 0; index < _dayHalfHours.length; index++) {
            let _halfHour = _dayHalfHours[index];
            let _bigTime = Math.floor(_halfHour / 2);
            _bigTime = _bigTime > 9 ? _bigTime : `0${_bigTime}`;
            let _time = `${_bigTime}:${_halfHour % 2 === 0 ? "00" : "30"}`;
            let _startHalfHour = _halfHour - 1;
            let _startBigTime = Math.floor((_halfHour - 1) / 2);
            _startBigTime =
              _startBigTime > 9 ? _startBigTime : `0${_startBigTime}`;
            let _startTime = `${_startBigTime}:${
              _startHalfHour % 2 === 0 ? "00" : "30"
            }`;
            if (!_dayTimeInfo.starttime) {
              _dayTimeInfo.starttime = _startTime;
              _dayTimeInfo.stoptime = _time;
              _dayTimeInfo.prevHalfHour = _halfHour;
            } else {
              if (Math.abs(_halfHour - _dayTimeInfo.prevHalfHour) > 1) {
                _times.push({
                  week: weekValue,
                  starttime: _dayTimeInfo.starttime,
                  stoptime:
                    _dayTimeInfo.stoptime === "24:00"
                      ? "23:59"
                      : _dayTimeInfo.stoptime
                });
                _dayTimeInfo.starttime = _startTime;
                _dayTimeInfo.stoptime = _time;
                _dayTimeInfo.prevHalfHour = _halfHour;
              } else {
                _dayTimeInfo.stoptime = _time;
                _dayTimeInfo.prevHalfHour = _halfHour;
              }
            }
          }
          _times.push({
            week: weekValue,
            starttime: _dayTimeInfo.starttime,
            stoptime:
              _dayTimeInfo.stoptime === "24:00"
                ? "23:59"
                : _dayTimeInfo.stoptime
          });
        }
      }
      this.$emit("timesChange", _times);
    },
    // 显示每个单元格标题
    getTimeTitle(weekItemLabel, halfHour) {
      let _startTime = "";
      let _endTime = "";
      let _startHalfHour = parseInt((halfHour - 1) / 2);
      _startHalfHour =
        _startHalfHour > 9 ? _startHalfHour : `0${_startHalfHour}`;
      let _startMinute = (halfHour - 1) % 2 === 0 ? "00" : "30";
      if (_startHalfHour === 24 && _startMinute === "00") {
        _startTime = "23:59";
      } else {
        _startTime = `${_startHalfHour}:${_startMinute}`;
      }
      let _hour = parseInt(halfHour / 2);
      _hour = _hour > 9 ? _hour : `0${_hour}`;
      let _minute = halfHour % 2 === 0 ? "00" : "30";
      if (_hour === 24 && _minute === "00") {
        _endTime = "23:59";
      } else {
        _endTime = `${_hour}:${_minute}`;
      }
      return `${weekItemLabel} ${_startTime}-${_endTime}`;
    },
    // 设置时间策略
    toSetTimeStrategy(weekIndex, halfHour) {
      let _weekItem = weekDay[weekIndex];
      if (!_weekItem) {
        return;
      }
      let weekValue = _weekItem.value;
      let _timeInfo = JSON.parse(JSON.stringify(this.timeInfo));
      if (!_timeInfo[weekValue]) {
        _timeInfo[weekValue] = [];
      }
      if (_timeInfo[weekValue].includes(halfHour)) {
        _timeInfo[weekValue] = _timeInfo[weekValue].filter(
          (_halfHour) => _halfHour !== halfHour
        );
      } else {
        _timeInfo[weekValue].push(halfHour);
      }
      this.timeInfo = _timeInfo;
    },
    // 设置临时时间
    toSetTempStrategy(weekIndex, halfHour) {
      let _weekItem = weekDay[weekIndex];
      if (!_weekItem) {
        return;
      }
      let weekValue = _weekItem.value;
      let _tempTimeInfo = this.tempTimeInfo;
      if (!_tempTimeInfo[weekValue]) {
        _tempTimeInfo[weekValue] = [];
      }
      if (_tempTimeInfo[weekValue].includes(halfHour)) {
        _tempTimeInfo[weekValue] = _tempTimeInfo[weekValue].filter(
          (_halfHour) => _halfHour !== halfHour
        );
      } else {
        _tempTimeInfo[weekValue].push(halfHour);
      }
      this.tempTimeInfo = _tempTimeInfo;
    },
    tableMousedown(event) {
      let timeInfo = event.target.dataset.time;
      if (timeInfo) {
        this.tempTimeInfo = JSON.parse(JSON.stringify(this.timeInfo));
        timeInfo = JSON.parse(timeInfo);
        this.tableMouseInfo = {
          // 是否开始选中
          start: true,
          // 开始选中的信息
          weekValue: timeInfo.weekValue,
          weekIndex: timeInfo.weekIndex,
          halfHour: timeInfo.halfHour
        };
      } else {
        this.initTableMouseInfo();
      }
    },
    tableMousemove(event) {
      let _mouseInfo = this.tableMouseInfo;
      if (_mouseInfo.start) {
        let timeInfo = event.target.dataset.time;
        if (timeInfo) {
          this.tempTimeInfo = JSON.parse(JSON.stringify(this.timeInfo));
          timeInfo = JSON.parse(timeInfo);
          for (
            let y = 0;
            y < Math.abs(timeInfo.weekIndex - _mouseInfo.weekIndex) + 1;
            y++
          ) {
            for (
              let x = 0;
              x < Math.abs(timeInfo.halfHour - _mouseInfo.halfHour) + 1;
              x++
            ) {
              let _yIndex =
                timeInfo.weekIndex - _mouseInfo.weekIndex >= 0
                  ? _mouseInfo.weekIndex + y
                  : _mouseInfo.weekIndex - y;
              let _xHalfHour =
                timeInfo.halfHour - _mouseInfo.halfHour >= 0
                  ? _mouseInfo.halfHour + x
                  : _mouseInfo.halfHour - x;
              this.toSetTempStrategy(_yIndex, _xHalfHour);
            }
          }
        }
      } else {
        this.tempTimeInfo = {};
      }
    },
    tableMouseup(event) {
      let _mouseInfo = this.tableMouseInfo;
      let timeInfo = event.target.dataset.time;
      if (timeInfo && _mouseInfo.start) {
        this.tableMouseInfo.start = false;
        timeInfo = JSON.parse(timeInfo);
        for (
          let y = 0;
          y < Math.abs(timeInfo.weekIndex - _mouseInfo.weekIndex) + 1;
          y++
        ) {
          for (
            let x = 0;
            x < Math.abs(timeInfo.halfHour - _mouseInfo.halfHour) + 1;
            x++
          ) {
            let _yIndex =
              timeInfo.weekIndex - _mouseInfo.weekIndex >= 0
                ? _mouseInfo.weekIndex + y
                : timeInfo.weekIndex + y;
            let _xHalfHour =
              timeInfo.halfHour - _mouseInfo.halfHour >= 0
                ? _mouseInfo.halfHour + x
                : timeInfo.halfHour + x;
            this.toSetTimeStrategy(_yIndex, _xHalfHour);
          }
        }
        this.timesChange();
      }
      this.initTableMouseInfo();
    },
    tableMouseleave() {
      this.initTableMouseInfo();
    },
    initTableMouseInfo() {
      this.tableMouseInfo = {
        // 是否开始选中
        start: false,
        // 开始选中的信息
        weekValue: null,
        weekIndex: null,
        halfHour: null
      };
      this.tempTimeInfo = {};
    }
  }
};
</script>

<style lang="less" scoped>
.time_root {
  .my_table {
    width: 100%;
    empty-cells: show;
    border-collapse: collapse;
    table-layout: fixed;
    border: 1px solid #dcdee2;
    border-spacing: 0;
    box-sizing: border-box;
    color: #333;
    font-size: 12px;
    .blank {
      width: 36px;
      background-color: #edf3ff;
    }
    th {
      padding: 0;
      line-height: 30px;
      font-weight: normal;
      text-align: center;
      vertical-align: middle;
      white-space: nowrap;
      background-color: #fff;
      border: 1px solid #ced9f2;
    }
    td {
      position: relative;
      padding: 0;
      line-height: 30px;
      text-align: center;
      vertical-align: middle;
      white-space: nowrap;
      border: 1px solid #ced9f2;
      &.cursor_pointer {
        cursor: pointer;
      }
      &.selected {
        background-color: #339dff;
      }
    }
  }
  .bottom_tip {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 16px;
    .bottom_tip_left {
      display: flex;
      justify-content: flex-start;
      align-items: center;
      .effective {
        margin-right: 4px;
        width: 10px;
        height: 10px;
        background-color: #339dff;
      }
      .invalid {
        margin-left: 16px;
        margin-right: 4px;
        width: 12px;
        height: 12px;
        border: 1px solid #dce4f6;
        background-color: #fff;
      }
    }
    .bottom_tip_right {
      font-size: 12px;
      color: #339dff;
    }
  }
}
</style>
