import { inject, reactive, ref, computed, watch, nextTick, onDeactivated, onUnmounted, onBeforeUnmount, provide, h, Teleport } from "vue";
import { defineVxeComponent } from "../../ui/src/comp.mjs";
import XEUtils from "xe-utils";
import "../../ui/index.mjs";
import { getFuncText, isEnableConf, getLastZIndex, nextZIndex } from "../../ui/src/utils.mjs";
import { getEventTargetNode, updatePanelPlacement } from "../../ui/src/dom.mjs";
import { handleValueFormat, parseDateObj, parseDateString, getRangeDateByCode } from "../../date-panel/src/util.mjs";
import { getSlotVNs } from "../../ui/src/vn.mjs";
import { errLog } from "../../ui/src/log.mjs";
import VxeDatePanelComponent from "../../date-panel/src/date-panel.mjs";
import VxeButtonComponent from "../../button/src/button.mjs";
import VxeButtonGroupComponent from "../../button/src/button-group.mjs";
import { getConfig } from "../../../../@vxe-ui/core/es/src/config.mjs";
import { useSize } from "../../../../@vxe-ui/core/es/src/useFns.mjs";
import { getI18n } from "../../../../@vxe-ui/core/es/src/i18n.mjs";
import { globalEvents, GLOBAL_EVENT_KEYS, createEvent } from "../../../../@vxe-ui/core/es/src/event.mjs";
import { renderEmptyElement } from "../../../../@vxe-ui/core/es/index.esm.mjs";
import { getIcon } from "../../../../@vxe-ui/core/es/src/icon.mjs";
import { commands } from "../../../../@vxe-ui/core/es/src/commands.mjs";
const VxeDateRangePickerComponent = defineVxeComponent({
  name: "VxeDateRangePicker",
  props: {
    modelValue: [String, Number, Date, Array],
    startValue: [String, Number, Date],
    endValue: [String, Number, Date],
    immediate: {
      type: Boolean,
      default: true
    },
    name: String,
    type: {
      type: String,
      default: "date"
    },
    clearable: {
      type: Boolean,
      default: () => getConfig().dateRangePicker.clearable
    },
    readonly: {
      type: Boolean,
      default: null
    },
    disabled: {
      type: Boolean,
      default: null
    },
    placeholder: String,
    autoComplete: {
      type: String,
      default: "off"
    },
    form: String,
    className: String,
    zIndex: Number,
    size: {
      type: String,
      default: () => getConfig().dateRangePicker.size || getConfig().size
    },
    // startDate: {
    //   type: [String, Number, Date] as PropType<VxeDateRangePickerPropTypes.StartDate>,
    //   default: () => getConfig().dateRangePicker.startDate
    // },
    // endDate: {
    //   type: [String, Number, Date] as PropType<VxeDateRangePickerPropTypes.EndDate>,
    //   default: () => getConfig().dateRangePicker.endDate
    // },
    minDate: [String, Number, Date],
    maxDate: [String, Number, Date],
    defaultDate: [String, Number, Date, Array],
    defaultTime: [String, Number, Date, Array],
    startDay: {
      type: [String, Number],
      default: () => getConfig().dateRangePicker.startDay
    },
    labelFormat: String,
    valueFormat: String,
    timeFormat: String,
    valueType: String,
    editable: {
      type: Boolean,
      default: true
    },
    festivalMethod: {
      type: Function,
      default: () => getConfig().dateRangePicker.festivalMethod
    },
    disabledMethod: {
      type: Function,
      default: () => getConfig().dateRangePicker.disabledMethod
    },
    separator: {
      type: [String, Number],
      default: () => getConfig().dateRangePicker.separator
    },
    // week
    selectDay: {
      type: [String, Number],
      default: () => getConfig().dateRangePicker.selectDay
    },
    showClearButton: {
      type: Boolean,
      default: () => getConfig().dateRangePicker.showClearButton
    },
    showConfirmButton: {
      type: Boolean,
      default: () => getConfig().dateRangePicker.showConfirmButton
    },
    autoClose: {
      type: Boolean,
      default: () => getConfig().dateRangePicker.autoClose
    },
    prefixIcon: String,
    suffixIcon: String,
    placement: String,
    transfer: {
      type: Boolean,
      default: null
    },
    timeConfig: Object,
    popupConfig: Object,
    shortcutConfig: Object
  },
  emits: [
    "update:modelValue",
    "update:startValue",
    "update:endValue",
    "input",
    "change",
    "keydown",
    "keyup",
    "click",
    "focus",
    "blur",
    "clear",
    "confirm",
    "prefix-click",
    "suffix-click",
    "date-prev",
    "date-today",
    "date-next",
    "shortcut-click"
  ],
  setup(props, context) {
    const { slots, emit } = context;
    const $xeModal = inject("$xeModal", null);
    const $xeDrawer = inject("$xeDrawer", null);
    const $xeTable = inject("$xeTable", null);
    const $xeForm = inject("$xeForm", null);
    const formItemInfo = inject("xeFormItemInfo", null);
    const xID = XEUtils.uniqueId();
    const { computeSize } = useSize(props);
    const reactData = reactive({
      initialized: false,
      panelIndex: 0,
      visiblePanel: false,
      isAniVisible: false,
      panelStyle: {},
      panelPlacement: "",
      isActivated: false,
      startValue: "",
      endValue: ""
    });
    const internalData = {
      // selectStatus: false
      // hpTimeout: undefined
    };
    const refElem = ref();
    const refInputTarget = ref();
    const refInputPanel = ref();
    const refPanelWrapper = ref();
    const refStartDatePanel = ref();
    const refEndDatePanel = ref();
    const refMaps = {
      refElem,
      refInput: refInputTarget
    };
    const $xeDateRangePicker = {
      xID,
      props,
      context,
      reactData,
      internalData,
      getRefMaps: () => refMaps
    };
    let dateRangePickerMethods = {};
    const computeBtnTransfer = computed(() => {
      const { transfer } = props;
      const popupOpts = computePopupOpts.value;
      if (XEUtils.isBoolean(popupOpts.transfer)) {
        return popupOpts.transfer;
      }
      if (transfer === null) {
        const globalTransfer = getConfig().dateRangePicker.transfer;
        if (XEUtils.isBoolean(globalTransfer)) {
          return globalTransfer;
        }
        if ($xeTable || $xeModal || $xeDrawer || $xeForm) {
          return true;
        }
      }
      return transfer;
    });
    const computeFormReadonly = computed(() => {
      const { readonly } = props;
      if (readonly === null) {
        if ($xeForm) {
          return $xeForm.props.readonly;
        }
        return false;
      }
      return readonly;
    });
    const computeIsDisabled = computed(() => {
      const { disabled } = props;
      if (disabled === null) {
        if ($xeForm) {
          return $xeForm.props.disabled;
        }
        return false;
      }
      return disabled;
    });
    const computeDefaultDates = computed(() => {
      const { defaultDate } = props;
      if (defaultDate) {
        if (XEUtils.isArray(defaultDate)) {
          return defaultDate;
        }
        if (`${defaultDate}`.indexOf(",") > -1) {
          return `${defaultDate}`.split(",");
        }
        return [defaultDate, defaultDate];
      }
      return [];
    });
    const computeDefaultTimes = computed(() => {
      const { defaultTime } = props;
      if (defaultTime) {
        if (XEUtils.isArray(defaultTime)) {
          return defaultTime;
        }
        if (`${defaultTime}`.indexOf(",") > -1) {
          return `${defaultTime}`.split(",");
        }
        return [defaultTime, defaultTime];
      }
      return [];
    });
    const computeMVal = computed(() => {
      const { startValue, endValue } = props;
      return `${startValue || ""}${endValue || ""}`;
    });
    const computeIsDateTimeType = computed(() => {
      const { type } = props;
      return type === "time" || type === "datetime";
    });
    const computeIsDatePickerType = computed(() => {
      return ["date", "week", "month", "quarter", "year"].indexOf(props.type) > -1;
    });
    const computeIsClearable = computed(() => {
      return props.clearable;
    });
    const computeInpPlaceholder = computed(() => {
      const { placeholder } = props;
      if (placeholder) {
        return getFuncText(placeholder);
      }
      const globalPlaceholder = getConfig().dateRangePicker.placeholder;
      if (globalPlaceholder) {
        return getFuncText(globalPlaceholder);
      }
      return getI18n("vxe.dateRangePicker.pleaseRange");
    });
    const computeInpImmediate = computed(() => {
      const { immediate } = props;
      return immediate;
    });
    const computeTimeOpts = computed(() => {
      return Object.assign({}, getConfig().dateRangePicker.timeConfig, props.timeConfig);
    });
    const computePopupOpts = computed(() => {
      return Object.assign({}, getConfig().dateRangePicker.popupConfig, props.popupConfig);
    });
    const computeShortcutOpts = computed(() => {
      return Object.assign({}, getConfig().dateRangePicker.shortcutConfig, props.shortcutConfig);
    });
    const computeShortcutList = computed(() => {
      const shortcutOpts = computeShortcutOpts.value;
      const { options } = shortcutOpts;
      if (options) {
        return options.map((option, index) => {
          return Object.assign({
            name: `${option.name || option.code || index}`
          }, option);
        });
      }
      return [];
    });
    const computeDateLabelFormat = computed(() => {
      const { labelFormat } = props;
      return labelFormat || getI18n(`vxe.input.date.labelFormat.${props.type}`);
    });
    const computeDateValueFormat = computed(() => {
      const { type, valueFormat } = props;
      return handleValueFormat(type, valueFormat);
    });
    const computeFirstDayOfWeek = computed(() => {
      const { startDay } = props;
      return XEUtils.toNumber(startDay);
    });
    const computePanelLabelObj = computed(() => {
      const { startValue, endValue } = reactData;
      const vals = startValue || endValue ? [startValue || "", endValue || ""] : [];
      return formatRangeLabel(vals);
    });
    const computeInputLabel = computed(() => {
      const panelLabelObj = computePanelLabelObj.value;
      return panelLabelObj.label;
    });
    const formatRangeLabel = (vals) => {
      const { type, separator } = props;
      const dateLabelFormat = computeDateLabelFormat.value;
      const dateValueFormat = computeDateValueFormat.value;
      const firstDayOfWeek = computeFirstDayOfWeek.value;
      const startRest = vals[0] ? parseDateObj(vals[0], type, {
        valueFormat: dateValueFormat,
        labelFormat: dateLabelFormat,
        firstDay: firstDayOfWeek
      }) : null;
      const endRest = vals[1] ? parseDateObj(vals[1], type, {
        valueFormat: dateValueFormat,
        labelFormat: dateLabelFormat,
        firstDay: firstDayOfWeek
      }) : null;
      const startLabel = startRest ? startRest.label : "";
      const endLabel = endRest ? endRest.label : "";
      return {
        label: (startLabel || endLabel ? [startLabel, endLabel] : []).join(`${separator || " ~ "}`),
        startLabel,
        endLabel
      };
    };
    const getRangeValue = (sValue, eValue) => {
      const { modelValue, valueType } = props;
      let isArr = XEUtils.isArray(modelValue);
      if (valueType) {
        switch (valueType) {
          case "array":
            isArr = true;
            break;
          case "string":
            isArr = false;
            break;
        }
      }
      if (sValue || eValue) {
        const rest = [sValue || "", eValue || ""];
        if (isArr) {
          return rest;
        }
        return rest.join(",");
      }
      return isArr ? [] : "";
    };
    const paraeUpdateModel = () => {
      const { type, modelValue } = props;
      const dateValueFormat = computeDateValueFormat.value;
      let sValue = "";
      let eValue = "";
      if (XEUtils.isArray(modelValue)) {
        const date1 = parseDateString(modelValue[0], type, { valueFormat: dateValueFormat });
        const date2 = parseDateString(modelValue[1], type, { valueFormat: dateValueFormat });
        if (date1 || date2) {
          sValue = date1 || "";
          eValue = date2 || "";
        }
      } else if (XEUtils.isString(modelValue)) {
        const strArr = modelValue.split(",");
        if (strArr[0] || strArr[1]) {
          sValue = strArr[0] || "";
          eValue = strArr[1] || "";
        }
      }
      return {
        sValue,
        eValue
      };
    };
    const parseUpdateData = () => {
      const { type, startValue, endValue } = props;
      const dateValueFormat = computeDateValueFormat.value;
      let sValue = "";
      let eValue = "";
      sValue = parseDateString(startValue, type, { valueFormat: dateValueFormat });
      eValue = parseDateString(endValue, type, { valueFormat: dateValueFormat });
      return {
        sValue,
        eValue
      };
    };
    const updateModelValue = (isModel) => {
      const { modelValue, startValue, endValue } = props;
      let restObj = {
        sValue: "",
        eValue: ""
      };
      if (isModel) {
        if (modelValue) {
          restObj = paraeUpdateModel();
        } else {
          restObj = parseUpdateData();
        }
      } else {
        if (startValue || endValue) {
          restObj = parseUpdateData();
        } else {
          restObj = paraeUpdateModel();
        }
      }
      reactData.startValue = restObj.sValue;
      reactData.endValue = restObj.eValue;
    };
    const triggerEvent = (evnt) => {
      const { startValue, endValue } = reactData;
      const value = getRangeValue(startValue, endValue);
      dispatchEvent(evnt.type, { value, startValue, endValue }, evnt);
    };
    const handleChange = (sValue, eValue, evnt) => {
      const { modelValue } = props;
      reactData.startValue = sValue;
      reactData.endValue = eValue;
      const value = getRangeValue(sValue, eValue);
      const isFinish = sValue && eValue || !sValue && !eValue;
      emit("update:modelValue", value);
      emit("update:startValue", sValue || "");
      emit("update:endValue", eValue || "");
      if (XEUtils.toValueString(modelValue) !== value) {
        dispatchEvent("change", { value, startValue: sValue, endValue: eValue, isFinish }, evnt);
        if ($xeForm && formItemInfo) {
          $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, value);
        }
      }
    };
    const changeEvent = (evnt) => {
      const inpImmediate = computeInpImmediate.value;
      if (!inpImmediate) {
        triggerEvent(evnt);
      }
    };
    const focusEvent = (evnt) => {
      reactData.isActivated = true;
      dateRangePickerOpenEvent(evnt);
      triggerEvent(evnt);
    };
    const clickPrefixEvent = (evnt) => {
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        const { startValue, endValue } = reactData;
        const value = getRangeValue(startValue, endValue);
        dispatchEvent("prefix-click", { value, startValue, endValue }, evnt);
      }
    };
    const hidePanel = () => {
      return new Promise((resolve) => {
        reactData.visiblePanel = false;
        internalData.hpTimeout = setTimeout(() => {
          reactData.isAniVisible = false;
          resolve();
        }, 350);
      });
    };
    const clearValueEvent = (evnt, value) => {
      const isDatePickerType = computeIsDatePickerType.value;
      if (isDatePickerType) {
        hidePanel();
      }
      const startValue = "";
      const endValue = "";
      handleChange(startValue, endValue, evnt);
      dispatchEvent("clear", { value, startValue, endValue }, evnt);
    };
    const checkValue = () => {
      const $startDatePanel = refStartDatePanel.value;
      const $endDatePanel = refEndDatePanel.value;
      if ($startDatePanel && $endDatePanel) {
        const startValue = $startDatePanel.getModelValue();
        const endValue = $endDatePanel.getModelValue();
        if (!startValue || !endValue) {
          handleChange("", "", { type: "check" });
        }
      }
    };
    const handleSelectClose = () => {
      const { autoClose } = props;
      const { startValue, endValue } = reactData;
      const { selectStatus } = internalData;
      const isDatePickerType = computeIsDatePickerType.value;
      if (autoClose) {
        if (selectStatus && isDatePickerType) {
          if (startValue && endValue) {
            hidePanel();
          }
        }
      } else {
        if (startValue && endValue) {
          internalData.selectStatus = false;
        }
      }
    };
    const clickSuffixEvent = (evnt) => {
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        const { startValue, endValue } = reactData;
        const value = getRangeValue(startValue, endValue);
        dispatchEvent("suffix-click", { value, startValue, endValue }, evnt);
      }
    };
    const blurEvent = (evnt) => {
      const { startValue, endValue } = reactData;
      const inpImmediate = computeInpImmediate.value;
      const value = "";
      if (!inpImmediate) {
        handleChange(startValue, endValue, evnt);
      }
      if (!reactData.visiblePanel) {
        reactData.isActivated = false;
      }
      dispatchEvent("blur", { value, startValue, endValue }, evnt);
      if ($xeForm && formItemInfo) {
        $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, value);
      }
    };
    const keydownEvent = (evnt) => {
      triggerEvent(evnt);
    };
    const keyupEvent = (evnt) => {
      triggerEvent(evnt);
    };
    const confirmEvent = (evnt) => {
      const $startDatePanel = refStartDatePanel.value;
      const $endDatePanel = refEndDatePanel.value;
      if ($startDatePanel && $endDatePanel) {
        const startValue = $startDatePanel.getModelValue();
        const endValue = $endDatePanel.getModelValue();
        if (startValue && !endValue || !startValue && endValue) {
          handleChange("", "", evnt);
        } else {
          $startDatePanel.confirmByEvent(evnt);
          $endDatePanel.confirmByEvent(evnt);
        }
        const value = getRangeValue(startValue, endValue);
        dispatchEvent("confirm", { value, startValue, endValue }, evnt);
      }
      hidePanel();
    };
    const startPanelChangeEvent = (params) => {
      const { selectStatus } = internalData;
      const { value, $event } = params;
      const endValue = selectStatus ? reactData.endValue : "";
      handleChange(value, endValue, $event);
      handleSelectClose();
      if (!selectStatus) {
        internalData.selectStatus = true;
      }
      nextTick(() => {
        const $startDatePanel = refStartDatePanel.value;
        const $endDatePanel = refEndDatePanel.value;
        if ($startDatePanel && $endDatePanel) {
          const startValue = $startDatePanel.getModelValue();
          if (!endValue && startValue) {
            $endDatePanel.setPanelDate(XEUtils.toStringDate(startValue));
          }
        }
      });
    };
    const endPanelChangeEvent = (params) => {
      const { selectStatus } = internalData;
      const { value, $event } = params;
      const startValue = selectStatus ? reactData.startValue : "";
      handleChange(startValue, value, $event);
      handleSelectClose();
      if (!selectStatus) {
        internalData.selectStatus = true;
      }
      nextTick(() => {
        const $startDatePanel = refStartDatePanel.value;
        const $endDatePanel = refEndDatePanel.value;
        if ($startDatePanel && $endDatePanel) {
          const endValue = $endDatePanel.getModelValue();
          if (!startValue && endValue) {
            $startDatePanel.setPanelDate(XEUtils.toStringDate(endValue));
          }
        }
      });
    };
    const handleGlobalMousedownEvent = (evnt) => {
      const { visiblePanel, isActivated } = reactData;
      const el = refElem.value;
      const panelWrapperElem = refPanelWrapper.value;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled && isActivated) {
        reactData.isActivated = getEventTargetNode(evnt, el).flag || getEventTargetNode(evnt, panelWrapperElem).flag;
        if (!reactData.isActivated) {
          if (visiblePanel) {
            checkValue();
            hidePanel();
          }
        }
      }
    };
    const handleGlobalKeydownEvent = (evnt) => {
      const { visiblePanel } = reactData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        const isTab = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.TAB);
        const isEsc = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ESCAPE);
        if (isTab) {
          reactData.isActivated = false;
        }
        if (visiblePanel) {
          if (isEsc || isTab) {
            checkValue();
            hidePanel();
          }
        }
      }
    };
    const handleGlobalMousewheelEvent = (evnt) => {
      const { visiblePanel } = reactData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        if (visiblePanel) {
          const panelWrapperElem = refPanelWrapper.value;
          if (getEventTargetNode(evnt, panelWrapperElem).flag) {
            updatePlacement();
          } else {
            checkValue();
            hidePanel();
          }
        }
      }
    };
    const handleGlobalBlurEvent = () => {
      const { visiblePanel, isActivated } = reactData;
      if (visiblePanel) {
        checkValue();
        hidePanel();
      }
      if (isActivated) {
        reactData.isActivated = false;
      }
      if (visiblePanel || isActivated) {
        const targetElem = refInputTarget.value;
        if (targetElem) {
          targetElem.blur();
        }
      }
    };
    const handleGlobalResizeEvent = () => {
      const { visiblePanel } = reactData;
      if (visiblePanel) {
        updatePlacement();
      }
    };
    const updateZindex = () => {
      const popupOpts = computePopupOpts.value;
      const customZIndex = popupOpts.zIndex || props.zIndex;
      if (customZIndex) {
        reactData.panelIndex = XEUtils.toNumber(customZIndex);
      } else if (reactData.panelIndex < getLastZIndex()) {
        reactData.panelIndex = nextZIndex();
      }
    };
    const updatePlacement = () => {
      const { placement } = props;
      const { panelIndex } = reactData;
      const targetElem = refInputTarget.value;
      const panelElem = refInputPanel.value;
      const btnTransfer = computeBtnTransfer.value;
      const popupOpts = computePopupOpts.value;
      const handleStyle = () => {
        const ppObj = updatePanelPlacement(targetElem, panelElem, {
          placement: popupOpts.placement || placement,
          teleportTo: btnTransfer
        });
        const panelStyle = Object.assign(ppObj.style, {
          zIndex: panelIndex
        });
        reactData.panelStyle = panelStyle;
        reactData.panelPlacement = ppObj.placement;
      };
      handleStyle();
      return nextTick().then(handleStyle);
    };
    const showPanel = () => {
      const { visiblePanel } = reactData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled && !visiblePanel) {
        if (!reactData.initialized) {
          reactData.initialized = true;
        }
        if (internalData.hpTimeout) {
          clearTimeout(internalData.hpTimeout);
          internalData.hpTimeout = void 0;
        }
        internalData.selectStatus = false;
        reactData.isActivated = true;
        reactData.isAniVisible = true;
        setTimeout(() => {
          reactData.visiblePanel = true;
          updatePlacement();
        }, 10);
        updateZindex();
        return updatePlacement();
      }
      return nextTick();
    };
    const dateRangePickerOpenEvent = (evnt) => {
      const formReadonly = computeFormReadonly.value;
      if (!formReadonly) {
        evnt.preventDefault();
        showPanel();
      }
    };
    const clickEvent = (evnt) => {
      triggerEvent(evnt);
    };
    const handleShortcutEvent = ({ option, $event }) => {
      const { type } = props;
      const shortcutOpts = computeShortcutOpts.value;
      const { autoClose } = shortcutOpts;
      const { code, clickMethod } = option;
      let startValue = reactData.startValue;
      let endValue = reactData.endValue;
      let value = getRangeValue(startValue, endValue);
      const shortcutParams = {
        $dateRangePicker: $xeDateRangePicker,
        option,
        value,
        startValue,
        endValue,
        code
      };
      if (!clickMethod && code) {
        const gCommandOpts = commands.get(code);
        const drpCommandMethod = gCommandOpts ? gCommandOpts.dateRangePickerCommandMethod : null;
        if (drpCommandMethod) {
          drpCommandMethod(shortcutParams);
        } else {
          const dateValueFormat = computeDateValueFormat.value;
          const firstDayOfWeek = computeFirstDayOfWeek.value;
          switch (code) {
            case "last1":
            case "last3":
            case "last7":
            case "last30":
            case "last60":
            case "last90":
            case "last180": {
              const restObj = getRangeDateByCode(code, value, type, {
                valueFormat: dateValueFormat,
                firstDay: firstDayOfWeek
              });
              startValue = restObj.startValue;
              endValue = restObj.endValue;
              value = getRangeValue(startValue, endValue);
              shortcutParams.value = value;
              shortcutParams.startValue = startValue;
              shortcutParams.endValue = endValue;
              handleChange(startValue, endValue, $event);
              break;
            }
            default:
              errLog("vxe.error.notCommands", [`[date-range-picker] ${code}`]);
              break;
          }
        }
      } else {
        const optClickMethod = clickMethod || shortcutOpts.clickMethod;
        if (optClickMethod) {
          optClickMethod(shortcutParams);
        }
      }
      if (autoClose) {
        hidePanel();
      }
      dispatchEvent("shortcut-click", shortcutParams, $event);
    };
    const dispatchEvent = (type, params, evnt) => {
      emit(type, createEvent(evnt, { $dateRangePicker: $xeDateRangePicker }, params));
    };
    dateRangePickerMethods = {
      dispatchEvent,
      setModelValue(startValue, endValue) {
        reactData.startValue = startValue || "";
        reactData.endValue = endValue || "";
        const value = getRangeValue(startValue, endValue);
        emit("update:modelValue", value);
      },
      setModelValueByEvent(evnt, startValue, endValue) {
        handleChange(startValue || "", endValue || "", evnt);
      },
      focus() {
        const inputElem = refInputTarget.value;
        reactData.isActivated = true;
        inputElem.focus();
        return nextTick();
      },
      blur() {
        const inputElem = refInputTarget.value;
        inputElem.blur();
        reactData.isActivated = false;
        return nextTick();
      },
      select() {
        const inputElem = refInputTarget.value;
        inputElem.select();
        reactData.isActivated = false;
        return nextTick();
      },
      showPanel,
      hidePanel,
      updatePlacement
    };
    Object.assign($xeDateRangePicker, dateRangePickerMethods);
    const renderShortcutBtn = (pos, isVertical) => {
      const shortcutOpts = computeShortcutOpts.value;
      const { position, align, mode } = shortcutOpts;
      const shortcutList = computeShortcutList.value;
      if (isEnableConf(shortcutOpts) && shortcutList.length && (position || "left") === pos) {
        return h("div", {
          class: `vxe-date-range-picker--layout-${pos}-wrapper`
        }, [
          h(VxeButtonGroupComponent, {
            options: shortcutList,
            mode,
            align,
            vertical: isVertical,
            onClick: handleShortcutEvent
          })
        ]);
      }
      return renderEmptyElement();
    };
    const renderPanel = () => {
      const { type, separator, autoClose, showConfirmButton, showClearButton } = props;
      const { initialized, isAniVisible, visiblePanel, panelPlacement, panelStyle, startValue, endValue } = reactData;
      const vSize = computeSize.value;
      const btnTransfer = computeBtnTransfer.value;
      const shortcutOpts = computeShortcutOpts.value;
      const isClearable = computeIsClearable.value;
      const panelLabelObj = computePanelLabelObj.value;
      const shortcutList = computeShortcutList.value;
      const isDateTimeType = computeIsDateTimeType.value;
      const defaultDates = computeDefaultDates.value;
      const defaultTimes = computeDefaultTimes.value;
      const timeOpts = computeTimeOpts.value;
      const popupOpts = computePopupOpts.value;
      const { startLabel, endLabel } = panelLabelObj;
      const { position } = shortcutOpts;
      const headerSlot = slots.header;
      const footerSlot = slots.footer;
      const topSlot = slots.top;
      const bottomSlot = slots.bottom;
      const leftSlot = slots.left;
      const rightSlot = slots.right;
      const ppClassName = popupOpts.className;
      const [sdDate, edDate] = defaultDates;
      const [sdTime, edTime] = defaultTimes;
      const hasShortcutBtn = shortcutList.length > 0;
      const showConfirmBtn = showConfirmButton === null ? isDateTimeType || !autoClose : showConfirmButton;
      const showClearBtn = showClearButton === null ? isClearable : showClearButton;
      return h(Teleport, {
        to: "body",
        disabled: btnTransfer ? !initialized : true
      }, [
        h("div", {
          ref: refInputPanel,
          class: ["vxe-table--ignore-clear vxe-date-range-picker--panel", `type--${type}`, ppClassName ? XEUtils.isFunction(ppClassName) ? ppClassName({ $dateRangePicker: $xeDateRangePicker }) : ppClassName : "", {
            [`size--${vSize}`]: vSize,
            "is--transfer": btnTransfer,
            "ani--leave": isAniVisible,
            "ani--enter": visiblePanel,
            "show--top": !!(topSlot || headerSlot || hasShortcutBtn && (position === "top" || position === "header")),
            "show--bottom": !!(bottomSlot || footerSlot || hasShortcutBtn && (position === "bottom" || position === "footer")),
            "show--left": !!(leftSlot || hasShortcutBtn && position === "left"),
            "show--right": !!(rightSlot || hasShortcutBtn && position === "right")
          }],
          placement: panelPlacement,
          style: panelStyle
        }, initialized && (visiblePanel || isAniVisible) ? [
          h("div", {
            ref: refPanelWrapper,
            class: ["vxe-date-range-picker--layout-all-wrapper", `type--${type}`, {
              [`size--${vSize}`]: vSize
            }]
          }, [
            topSlot ? h("div", {
              class: "vxe-date-range-picker--layout-top-wrapper"
            }, topSlot({})) : renderShortcutBtn("top"),
            h("div", {
              class: "vxe-date-range-picker--layout-body-layout-wrapper"
            }, [
              leftSlot ? h("div", {
                class: "vxe-date-range-picker--layout-left-wrapper"
              }, leftSlot({})) : renderShortcutBtn("left", true),
              h("div", {
                class: "vxe-date-range-picker--layout-body-content-wrapper"
              }, [
                headerSlot ? h("div", {
                  class: "vxe-date-range-picker--layout-header-wrapper"
                }, headerSlot({})) : renderShortcutBtn("header"),
                h("div", {
                  class: "vxe-date-range-picker--layout-body-wrapper"
                }, [
                  h(VxeDatePanelComponent, {
                    ref: refStartDatePanel,
                    modelValue: startValue,
                    type: props.type,
                    className: props.className,
                    minDate: props.minDate,
                    maxDate: props.maxDate,
                    endDate: endValue,
                    startDay: props.startDay,
                    labelFormat: props.labelFormat,
                    valueFormat: props.valueFormat,
                    timeFormat: props.timeFormat,
                    defaultDate: sdDate,
                    defaultTime: sdTime,
                    timeConfig: timeOpts,
                    festivalMethod: props.festivalMethod,
                    disabledMethod: props.disabledMethod,
                    selectDay: props.selectDay,
                    onChange: startPanelChangeEvent
                  }),
                  h(VxeDatePanelComponent, {
                    ref: refEndDatePanel,
                    modelValue: endValue,
                    type: props.type,
                    className: props.className,
                    minDate: props.minDate,
                    maxDate: props.maxDate,
                    startDate: startValue,
                    startDay: props.startDay,
                    labelFormat: props.labelFormat,
                    valueFormat: props.valueFormat,
                    timeFormat: props.timeFormat,
                    defaultDate: edDate,
                    defaultTime: edTime,
                    timeConfig: timeOpts,
                    festivalMethod: props.festivalMethod,
                    disabledMethod: props.disabledMethod,
                    selectDay: props.selectDay,
                    onChange: endPanelChangeEvent
                  })
                ]),
                h("div", {
                  class: "vxe-date-range-picker--layout-footer-wrapper"
                }, [
                  h("div", {
                    class: "vxe-date-range-picker--layout-footer-label"
                  }, startLabel || endLabel ? [
                    h("span", startLabel),
                    h("span", `${separator || ""}`),
                    h("span", endLabel)
                  ] : `${separator || ""}`),
                  h("div", {
                    class: "vxe-date-range-picker--layout-footer-custom"
                  }, footerSlot ? footerSlot({}) : [renderShortcutBtn("footer")]),
                  h("div", {
                    class: "vxe-date-range-picker--layout-footer-btns"
                  }, [
                    showClearBtn ? h(VxeButtonComponent, {
                      size: "mini",
                      disabled: !(startValue || endValue),
                      content: getI18n("vxe.button.clear"),
                      onClick: clearValueEvent
                    }) : renderEmptyElement(),
                    showConfirmBtn ? h(VxeButtonComponent, {
                      size: "mini",
                      status: "primary",
                      content: getI18n("vxe.button.confirm"),
                      onClick: confirmEvent
                    }) : renderEmptyElement()
                  ])
                ])
              ]),
              rightSlot ? h("div", {
                class: "vxe-date-range-picker--layout-right-wrapper"
              }, rightSlot({})) : renderShortcutBtn("right", true)
            ]),
            bottomSlot ? h("div", {
              class: "vxe-date-range-picker--layout-bottom-wrapper"
            }, bottomSlot({})) : renderShortcutBtn("bottom")
          ])
        ] : [])
      ]);
    };
    const renderPrefixIcon = () => {
      const { prefixIcon } = props;
      const prefixSlot = slots.prefix;
      return prefixSlot || prefixIcon ? h("div", {
        class: "vxe-date-range-picker--prefix",
        onClick: clickPrefixEvent
      }, [
        h("div", {
          class: "vxe-date-range-picker--prefix-icon"
        }, prefixSlot ? getSlotVNs(prefixSlot({})) : [
          h("i", {
            class: prefixIcon
          })
        ])
      ]) : null;
    };
    const renderSuffixIcon = () => {
      const { suffixIcon } = props;
      const { startValue, endValue } = reactData;
      const suffixSlot = slots.suffix;
      const isDisabled = computeIsDisabled.value;
      const isClearable = computeIsClearable.value;
      return h("div", {
        class: ["vxe-date-range-picker--suffix", {
          "is--clear": isClearable && !isDisabled && (startValue || endValue)
        }]
      }, [
        isClearable ? h("div", {
          class: "vxe-date-range-picker--clear-icon",
          onClick: clearValueEvent
        }, [
          h("i", {
            class: getIcon().INPUT_CLEAR
          })
        ]) : renderEmptyElement(),
        renderExtraSuffixIcon(),
        suffixSlot || suffixIcon ? h("div", {
          class: "vxe-date-range-picker--suffix-icon",
          onClick: clickSuffixEvent
        }, suffixSlot ? getSlotVNs(suffixSlot({})) : [
          h("i", {
            class: suffixIcon
          })
        ]) : renderEmptyElement()
      ]);
    };
    const renderExtraSuffixIcon = () => {
      return h("div", {
        class: "vxe-date-range-picker--control-icon",
        onClick: dateRangePickerOpenEvent
      }, [
        h("i", {
          class: ["vxe-date-range-picker--date-picker-icon", getIcon().DATE_PICKER_DATE]
        })
      ]);
    };
    const renderVN = () => {
      const { className, type, name, autoComplete } = props;
      const { startValue, endValue, visiblePanel, isActivated } = reactData;
      const vSize = computeSize.value;
      const isDisabled = computeIsDisabled.value;
      const formReadonly = computeFormReadonly.value;
      const inputLabel = computeInputLabel.value;
      if (formReadonly) {
        return h("div", {
          ref: refElem,
          class: ["vxe-date-range-picker--readonly", `type--${type}`, className]
        }, inputLabel);
      }
      const inpPlaceholder = computeInpPlaceholder.value;
      const isClearable = computeIsClearable.value;
      const prefix = renderPrefixIcon();
      const suffix = renderSuffixIcon();
      return h("div", {
        ref: refElem,
        class: ["vxe-date-range-picker", `type--${type}`, className, {
          [`size--${vSize}`]: vSize,
          "is--prefix": !!prefix,
          "is--suffix": !!suffix,
          "is--visible": visiblePanel,
          "is--disabled": isDisabled,
          "is--active": isActivated,
          "show--clear": isClearable && !isDisabled && (startValue || endValue)
        }],
        spellcheck: false
      }, [
        prefix || renderEmptyElement(),
        h("div", {
          class: "vxe-date-range-picker--wrapper"
        }, [
          h("input", {
            ref: refInputTarget,
            class: "vxe-date-range-picker--inner",
            value: inputLabel,
            name,
            type: "text",
            placeholder: inpPlaceholder,
            editable: false,
            disabled: isDisabled,
            autocomplete: autoComplete,
            onKeydown: keydownEvent,
            onKeyup: keyupEvent,
            onClick: clickEvent,
            onChange: changeEvent,
            onFocus: focusEvent,
            onBlur: blurEvent
          })
        ]),
        suffix || renderEmptyElement(),
        // 下拉面板
        renderPanel()
      ]);
    };
    watch(() => props.modelValue, () => {
      updateModelValue(true);
    });
    watch(computeMVal, () => {
      updateModelValue(false);
    });
    updateModelValue(true);
    nextTick(() => {
      globalEvents.on($xeDateRangePicker, "mousewheel", handleGlobalMousewheelEvent);
      globalEvents.on($xeDateRangePicker, "mousedown", handleGlobalMousedownEvent);
      globalEvents.on($xeDateRangePicker, "keydown", handleGlobalKeydownEvent);
      globalEvents.on($xeDateRangePicker, "blur", handleGlobalBlurEvent);
      globalEvents.on($xeDateRangePicker, "resize", handleGlobalResizeEvent);
    });
    onDeactivated(() => {
      checkValue();
    });
    onUnmounted(() => {
      globalEvents.off($xeDateRangePicker, "mousewheel");
      globalEvents.off($xeDateRangePicker, "mousedown");
      globalEvents.off($xeDateRangePicker, "blur");
      globalEvents.off($xeDateRangePicker, "resize");
    });
    onBeforeUnmount(() => {
      checkValue();
    });
    provide("$xeDateRangePicker", $xeDateRangePicker);
    $xeDateRangePicker.renderVN = renderVN;
    return $xeDateRangePicker;
  },
  render() {
    return this.renderVN();
  }
});
export {
  VxeDateRangePickerComponent as default
};
