<!--
 * @Company: 沈阳信诚科技
 * @Email: html_venustar@163.com
 * @Author: Liuqiming
 * @Description: 日期时间选择控件 限制日期及时间范围
 * @LastEditors: Liuqiming
 * @LastEditTime: 2024-03-27 09:21:42
 * @Date: 2024-03-07 16:26:57
-->
<template>
  <div class="data-time-range-container" :style="{width: width}" key="els-date-time-range">
    <el-date-picker
      v-model="startTime"
      type="datetime"
      :key="`date-time-range-start-time`"
      :placeholder="placeholder[0] || 'start-time'"
      :format="format"
      :value-format="valueFormat"
      :clearable="false"
      class="start-select"
      popper-class="data-time-range-select"
      @change="
        (val) => {
          handlerChange('start', val)
        }
      "
      @visible-change="
        (val) => {
          handlerVisible('start',val)
        }
      "
      :disabled="disabled"
    />
    <span class="range"> {{ rangeSeparator }} </span>
    <el-date-picker
      v-model="endTime"
      type="datetime"
      :key="`date-time-range-end-time`"
      :placeholder="placeholder[1] || 'end-time'"
      :format="format"
      :value-format="valueFormat"
      :clearable="false"
      class="end-select"
      popper-class="data-time-range-select"
      @change="
        (val) => {
          handlerChange('end', val)
        }
      "
      @visible-change="
        (val) => {
          handlerVisible('end',val)
        }
      "
      :disabled="disabled || startTime == '' || !startTime"
      :disabled-date="disabledDate"
      :disabled-hours="disabledHours"
      :disabled-minutes="disabledMinutes"
    >
      <template #default="cell">
        <div class="el-date-table-cell" @click="handlerCellClick(cell)">
          <span class="el-date-table-cell__text">{{ cell.text }}</span>
        </div>
      </template>
    </el-date-picker>
    <el-icon
      v-if="clearable"
      class="data-time-range-select-clear"
      @click="handlerClear"
      :class="disabled ? 'is_disabled' : ''"
    ><CircleClose /></el-icon>
  </div>
</template>

<script setup>
import { parseTime } from '@U/cfhi.js'
import { nextTick } from 'vue';
const props = defineProps({
  // 数据
  width: {
    type: String,
    default: 'auto',
  },
  rangeSeparator: {
    type: String,
    default: '至',
  },
  clearable: {
    type: Boolean,
    default: true,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  format: {
    type: String,
    default: 'YYYY-MM-DD HH:mm',
  },
  valueFormat: {
    type: String,
    default: 'YYYY-MM-DD HH:mm',
  },
  placeholder: {
    type: Array,
    default: () => ['开始时间', '结束时间'],
  },
  // 时间间隔范围 --- 时间戳长度，默认24小时
  range: {
    type: Number,
    default: 86400000,
  },
  // 当前的值
  modelValue: Array,
});
const startTime = ref('')
const endTime = ref('')
// 双向绑定-设置modelValue的值
const emit = defineEmits(['update:modelValue', 'change', 'visibleChange']);
const setModelValue = (val=[startTime.value, endTime.value]) => {
  emit('update:modelValue', val)
}
// 记录结束时间日期所选数据
const tempDay = ref(null)
// 初始化回显
watch(() => props.modelValue, (val) => {
  if (val && val.length === 2) {
    startTime.value = parseTime(new Date(val[0]), '{y}-{m}-{d} {h}:{i}')
    endTime.value = parseTime(new Date(val[1]), '{y}-{m}-{d} {h}:{i}')
    tempDay.value = new Date(val[1]).getDate()
  } else {
    startTime.value = ''
    endTime.value = ''
    tempDay.value = null
  }
},{immediate: true, deep: true})
// 清空
const handlerClear = () => {
  if (!props.disabled) {
    startTime.value = ''
    endTime.value = ''
    setModelValue()
    handlerChange()
  }
}
// 组件change事件
const handlerChange = (status, val) => {
  let startTimeTemp = new Date(startTime.value).getTime()
  let endTimeTemp = new Date(endTime.value).getTime()
  let valTimeTemp = new Date(val).getTime()
  // 设置可选范围
  if (status === 'start') {
    if (!endTimeTemp || (endTimeTemp - valTimeTemp) > props.range || (endTimeTemp - valTimeTemp) < 0) {
      endTime.value = parseTime((valTimeTemp + props.range), '{y}-{m}-{d} {h}:{i}')
      tempDay.value = new Date(endTime.value).getDate()
    }
  } else {
    if (!startTimeTemp || (valTimeTemp - startTimeTemp) > props.range || (valTimeTemp - startTimeTemp) < 0) {
      startTime.value = parseTime((new Date(val).getTime() - props.range), '{y}-{m}-{d} {h}:{i}')
      tempDay.value = new Date(valTimeTemp).getDate()
    }
  }
  // 触发回调change事件
  emit('change', [startTime.value, endTime.value])
}
const disabledDate = (date) => {
  if (new Date(startTime.value).getMinutes() === 0 && new Date(startTime.value).getHours() === 0){
    return date.getTime() < new Date(startTime.value).getTime() || date.getTime() > (new Date(startTime.value).getTime() + props.range)
  } else {
    return date.getTime() < (new Date(startTime.value).getTime() - 86400000) || date.getTime() > (new Date(startTime.value).getTime() + props.range)
  }
}
const disabledHours = () => {
  let startHours = new Date(startTime.value).getHours()
  if (tempDay.value === new Date(startTime.value).getDate()) {
    let disabled = []
    for(let i = 0; i < startHours; i++) {
      disabled.push(i)
    }
    return disabled
  } else {
    let disabled = []
    for(let i = 23; i > startHours; i--) {
      disabled.push(i)
    }
    return disabled
  }
}
const disabledMinutes = () => {
  let startMinutes = new Date(startTime.value).getMinutes()
  if (tempDay.value === new Date(startTime.value).getDate()) {
    let disabled = []
    for(let i = 0; i < startMinutes; i++) {
      disabled.push(i)
    }
    return disabled
  } else {
    let disabled = []
    for(let i = 59; i > startMinutes; i--) {
      disabled.push(i)
    }
    return disabled
  }
}
const handlerCellClick = (cell) => {
  tempDay.value = cell.text
}
// popper 弹出隐藏事件
const handlerVisible = (status,val) => {
  emit('visibleChange', status, val)
}
nextTick(()=>{
  setModelValue()
})
</script>

<style lang="scss" scoped>
.data-time-range-container{
  min-width: 340px !important;
  display: inline-block;
  border: 1px solid var(--el-input-border-color, var(--el-border-color));
  border-radius: 3px;
  height: 32px;
  line-height: 32px;
  transition: all 0.25s;
  .range{
    display: inline-block;
    width: calc(8% - 24px);
    height: 30px;
    line-height: 30px;
    text-align: center;
    vertical-align: top;
    color: #a8abb2;
  }
  .data-time-range-select-clear{
    color: #a8abb2;
    line-height: 32px;
    cursor: pointer;
    transition: all 0.25s;
  }
  .data-time-range-select-clear:hover{
    color: var(--el-color-primary);
  }
  :deep(.el-date-editor){
    width: 46%;
    height: 30px;
  }
  :deep(.el-input){
    vertical-align: top;
  }
  :deep(.el-input__inner){
    text-align: center;
  }
  :deep(.el-input__wrapper){
    box-shadow: none;
    background: none;
    line-height: 30px;
  }
  :deep(.end-select){
    .el-input__wrapper{
      .el-input__prefix{
        display: none !important;
      }
    }
  }
}
.is_disabled{
  cursor: not-allowed !important;
}
.data-time-range-container:focus-within{
  border: 1px solid var(--el-color-primary) !important;
}
</style>
<style lang="scss">
.data-time-range-select{
  .el-date-picker__editor-wrap:first-child{
    display: none;
  }
}
</style>