<template>
  <div class="s-datetimerange">
    <el-date-picker
      :value="startTime"
      @input="updateStartTime"
      :type="type"
      default-time="00:00:00"
      :disabled="disabled"
      :placeholder="startTimePlaceholder"
      :value-format="valueFormat"
      :picker-options="startTimePickerOptions"
    />
    <span class="s-separator">{{ rangeSeparator }}</span>
    <el-date-picker
      :value="endTime"
      @input="updateEndTime"
      :type="type"
      default-time="23:59:59"
      :disabled="disabled"
      :placeholder="endTimePlaceholder"
      :value-format="valueFormat"
      :picker-options="endTimePickerOptions"
    />
  </div>
</template>

<script>
import startOfDay from "date-fns/startOfDay";
import endOfDay from "date-fns/endOfDay";

export default {
  name: "SeparatDateTimeRange",
  props: {
    // 开始时间，支持.sync
    startTime: {
      type: String,
      default: "",
    },
    // 结束时间，支持.sync
    endTime: {
      type: String,
      default: "",
    },
    // 显示类型 year/month/date/week/datetime
    type: {
      type: String,
      default: "datetime",
    },
    // 分隔符
    rangeSeparator: {
      type: String,
      default: "-",
    },
    // 禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // 占位符，使用数组可分别设置开始和结束占位符
    placeholder: {
      type: [String, Array],
      default: "请选择日期时间",
    },
    // 值格式，默认yyyy-MM-dd HH:mm:ss
    valueFormat: {
      type: String,
      default: "yyyy-MM-dd HH:mm:ss",
    },
    // 开始日期禁用
    startTimeDisabledDate: {
      type: Function,
      default: (date, endTime, fromNow, toNow) => {
        const dateTime = startOfDay(date).getTime();
        const nowTime = Date.now();

        if (toNow && (!endTime || new Date(endTime).getTime() > nowTime)) {
          endTime = nowTime;
        }

        return (
          (fromNow && dateTime < nowTime) ||
          (endTime && dateTime > new Date(endTime).getTime())
        );
      },
    },
    // 结束日期禁用
    endTimeDisabledDate: {
      type: Function,
      default: (date, startTime, fromNow, toNow) => {
        const dateTime = endOfDay(date).getTime();
        const nowTime = Date.now();

        if (
          fromNow &&
          (!startTime || new Date(startTime).getTime() < nowTime)
        ) {
          fromNow = nowTime;
        }

        return (
          (toNow && date.getTime() > nowTime) ||
          (startTime && dateTime < new Date(startTime).getTime())
        );
      },
    },
    // 从现在开始，设置为true时，开始时间最早从现在开始 （为true时将忽略toNow设置）
    fromNow: {
      type: Boolean,
      default: false,
    },
    // 到现在截止，设置为true时，截止时间最晚到现在截止
    toNow: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      startTimePickerOptions: {
        disabledDate: date =>
          this.startTimeDisabledDate(
            date,
            this.endTime,
            this.fromNow,
            this.toNow
          ),
      },
      endTimePickerOptions: {
        disabledDate: date =>
          this.endTimeDisabledDate(
            date,
            this.startTime,
            this.fromNow,
            this.toNow
          ),
      },
    };
  },
  computed: {
    // 开始日期占位符
    startTimePlaceholder() {
      return Array.isArray(this.placeholder)
        ? this.placeholder[0]
        : this.placeholder;
    },
    // 结束日期占位符
    endTimePlaceholder() {
      return Array.isArray(this.placeholder)
        ? this.placeholder[1]
        : this.placeholder;
    },
  },
  methods: {
    updateStartTime(val) {
      if (
        this.endTime &&
        new Date(val).getTime() > new Date(this.endTime).getTime()
      ) {
        this.$emit("update:startTime", this.endTime);
        this.$emit("update:endTime", val);
      } else {
        this.$emit("update:startTime", val || "");
      }
    },
    updateEndTime(val) {
      if (
        this.startTime &&
        new Date(val).getTime() < new Date(this.startTime).getTime()
      ) {
        this.$emit("update:startTime", val);
        this.$emit("update:endTime", this.startTime);
      } else {
        this.$emit("update:endTime", val || "");
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.s-datetimerange {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
}
.s-separator {
  padding: 0 5px;
  text-align: center;
}
</style>
