import { defineComponent, ref, computed, watch, nextTick, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, renderSlot, withModifiers, createBlock } from 'vue';
import { isArray } from 'lodash-es';
import { format, isValid } from 'date-fns';
import getPrefixCls from '../_util/getPrefixCls';
import { useInput } from '../_util/use/useInput';
import { CloseCircleFilled } from '../icon';
import { isEmptyValue, strictParse, isBeyondRangeTime } from './helper';

const prefixCls = getPrefixCls('range-input');
const rangeInputProps = {
  format: String,
  selectedDates: {
    type: Array
  },
  changeSelectedDates: Function,
  separator: String,
  maxRange: String,
  clearable: Boolean,
  disabled: {
    type: Boolean,
    default: false
  },
  placeholder: [String, Array],
  innerIsFocus: Boolean,
  innerIsError: Boolean
};
function useMouse(emit) {
  const hovering = ref(false);
  const onMouseLeave = e => {
    hovering.value = false;
    emit('mouseleave', e);
  };
  const onMouseEnter = e => {
    hovering.value = true;
    emit('mouseenter', e);
  };
  return {
    hovering,
    onMouseLeave,
    onMouseEnter
  };
}
function useRangeInput(props, currentPosition, anotherPosition) {
  const inputText = ref();
  const resetInputValue = () => {
    inputText.value = isEmptyValue(props.selectedDates) ? '' : format(props.selectedDates[currentPosition], props.format);
  };
  watch([() => props.selectedDates, () => props.format], resetInputValue, {
    immediate: true
  });
  const updateInputText = val => {
    var _props$selectedDates, _props$selectedDates2;
    inputText.value = val;
    const date = strictParse(val, props.format, new Date());
    if (isValid(date) && !isBeyondRangeTime({
      flagDate: ((_props$selectedDates = props.selectedDates) === null || _props$selectedDates === void 0 ? void 0 : _props$selectedDates[anotherPosition]) && new Date((_props$selectedDates2 = props.selectedDates) === null || _props$selectedDates2 === void 0 ? void 0 : _props$selectedDates2[anotherPosition]),
      currentDate: date,
      maxRange: props.maxRange,
      format: props.format
    })) {
      // update selectedDates
      const dates = [...props.selectedDates];
      dates[currentPosition] = date.getTime();
      props.changeSelectedDates(dates);
    }
  };
  const {
    handleInput,
    handleCompositionStart,
    handleCompositionEnd
  } = useInput(updateInputText);
  return {
    inputText,
    handleInput,
    resetInputValue,
    handleCompositionStart,
    handleCompositionEnd
  };
}
function useLeftInput(props) {
  const {
    inputText,
    handleInput,
    resetInputValue,
    handleCompositionStart,
    handleCompositionEnd
  } = useRangeInput(props, 0, 1);
  return {
    leftInputText: inputText,
    resetLeftInputText: resetInputValue,
    onLeftInput: handleInput,
    onLeftCompositionStart: handleCompositionStart,
    onLeftCompositionEnd: handleCompositionEnd
  };
}
function useRightInput(props) {
  const {
    inputText,
    handleInput,
    resetInputValue,
    handleCompositionStart,
    handleCompositionEnd
  } = useRangeInput(props, 1, 0);
  return {
    rightInputText: inputText,
    resetRightInputText: resetInputValue,
    onRightInput: handleInput,
    onRightCompositionStart: handleCompositionStart,
    onRightCompositionEnd: handleCompositionEnd
  };
}
function useFocusBlur(props, emit) {
  const isFocus = ref(false);
  let againFocusFlag = false;
  watch(() => props.innerIsFocus, () => {
    if (props.innerIsFocus) {
      isFocus.value = true;
    }
  });
  const onFocus = e => {
    if (!isFocus.value) {
      isFocus.value = true;
      emit('focus', e);
    } else {
      againFocusFlag = true;
    }
  };
  const onBlur = e => {
    // 延迟 blur，防止 focus 内部的 input 触发 blur
    nextTick(() => {
      if (isFocus.value) {
        if (!againFocusFlag) {
          isFocus.value = false;
          emit('blur', e);
        } else {
          // 再延迟 blur，并且重置 againFocusFlag
          nextTick(() => {
            againFocusFlag = false;
            isFocus.value = false;
            emit('blur', e);
          });
        }
      }
    });
  };
  return {
    onFocus,
    onBlur
  };
}
var script = defineComponent({
  components: {
    CloseCircleFilled
  },
  props: rangeInputProps,
  emits: ['clear', 'blur', 'focus', 'mouseleave', 'mouseenter'],
  setup(props, _ref) {
    let {
      emit
    } = _ref;
    const inputRangeRefEl = ref();
    const innerPlaceHolder = computed(() => isArray(props.placeholder) ? props.placeholder : [props.placeholder, props.placeholder]);
    const {
      hovering,
      onMouseLeave,
      onMouseEnter
    } = useMouse(emit);
    const {
      leftInputText,
      resetLeftInputText,
      onLeftInput,
      onLeftCompositionStart,
      onLeftCompositionEnd
    } = useLeftInput(props);
    const {
      rightInputText,
      resetRightInputText,
      onRightInput,
      onRightCompositionStart,
      onRightCompositionEnd
    } = useRightInput(props);
    const showClear = computed(() => {
      var _props$selectedDates3;
      return props.clearable && !props.disabled && ((_props$selectedDates3 = props.selectedDates) === null || _props$selectedDates3 === void 0 ? void 0 : _props$selectedDates3.length) && hovering.value;
    });
    const clear = () => {
      emit('clear');
    };
    const {
      onFocus,
      onBlur
    } = useFocusBlur(props, emit);
    const focus = () => {
      if (!props.disabled) {
        inputRangeRefEl.value.focus();
      }
    };
    const blur = () => {
      inputRangeRefEl.value.blur();
    };
    return {
      inputRangeRefEl,
      prefixCls,
      innerPlaceHolder,
      leftInputText,
      onLeftInput,
      onLeftCompositionStart,
      onLeftCompositionEnd,
      rightInputText,
      onRightInput,
      onRightCompositionStart,
      onRightCompositionEnd,
      onFocus,
      onBlur: event => {
        resetLeftInputText();
        resetRightInputText();
        onBlur(event);
      },
      focus,
      blur,
      onMouseLeave,
      onMouseEnter,
      showClear,
      clear
    };
  }
});

const _hoisted_1 = ["tabindex"];
const _hoisted_2 = ["value", "placeholder", "disabled"];
const _hoisted_3 = ["value", "placeholder", "disabled"];
function render(_ctx, _cache, $props, $setup, $data, $options) {
  const _component_CloseCircleFilled = resolveComponent("CloseCircleFilled");
  return openBlock(), createElementBlock("span", {
    ref: "inputRangeRefEl",
    class: normalizeClass([_ctx.prefixCls, _ctx.disabled && 'is-disabled', _ctx.innerIsFocus && 'is-focused', _ctx.innerIsError && 'is-error']),
    tabindex: _ctx.disabled ? null : 0,
    onMouseenter: _cache[11] || (_cache[11] = function () {
      return _ctx.onMouseEnter && _ctx.onMouseEnter(...arguments);
    }),
    onMouseleave: _cache[12] || (_cache[12] = function () {
      return _ctx.onMouseLeave && _ctx.onMouseLeave(...arguments);
    }),
    onFocus: _cache[13] || (_cache[13] = function () {
      return _ctx.onFocus && _ctx.onFocus(...arguments);
    }),
    onBlur: _cache[14] || (_cache[14] = function () {
      return _ctx.onBlur && _ctx.onBlur(...arguments);
    })
  }, [createElementVNode("input", {
    class: normalizeClass(`${_ctx.prefixCls}-inner`),
    value: _ctx.leftInputText,
    placeholder: _ctx.innerPlaceHolder[0],
    disabled: _ctx.disabled,
    onCompositionstart: _cache[0] || (_cache[0] = function () {
      return _ctx.onLeftCompositionStart && _ctx.onLeftCompositionStart(...arguments);
    }),
    onCompositionend: _cache[1] || (_cache[1] = function () {
      return _ctx.onLeftCompositionEnd && _ctx.onLeftCompositionEnd(...arguments);
    }),
    onInput: _cache[2] || (_cache[2] = function () {
      return _ctx.onLeftInput && _ctx.onLeftInput(...arguments);
    }),
    onFocus: _cache[3] || (_cache[3] = function () {
      return _ctx.onFocus && _ctx.onFocus(...arguments);
    }),
    onBlur: _cache[4] || (_cache[4] = function () {
      return _ctx.onBlur && _ctx.onBlur(...arguments);
    })
  }, null, 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_2), createElementVNode("span", {
    class: normalizeClass(`${_ctx.prefixCls}-separator`)
  }, [renderSlot(_ctx.$slots, "separator")], 2 /* CLASS */), createElementVNode("input", {
    class: normalizeClass(`${_ctx.prefixCls}-inner`),
    value: _ctx.rightInputText,
    placeholder: _ctx.innerPlaceHolder[1],
    disabled: _ctx.disabled,
    onCompositionstart: _cache[5] || (_cache[5] = function () {
      return _ctx.onRightCompositionStart && _ctx.onRightCompositionStart(...arguments);
    }),
    onCompositionend: _cache[6] || (_cache[6] = function () {
      return _ctx.onRightCompositionEnd && _ctx.onRightCompositionEnd(...arguments);
    }),
    onInput: _cache[7] || (_cache[7] = function () {
      return _ctx.onRightInput && _ctx.onRightInput(...arguments);
    }),
    onFocus: _cache[8] || (_cache[8] = function () {
      return _ctx.onFocus && _ctx.onFocus(...arguments);
    }),
    onBlur: _cache[9] || (_cache[9] = function () {
      return _ctx.onBlur && _ctx.onBlur(...arguments);
    })
  }, null, 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_3), createElementVNode("span", {
    class: normalizeClass(`${_ctx.prefixCls}-suffix`),
    onMousedown: _cache[10] || (_cache[10] = withModifiers(() => {}, ["prevent"]))
  }, [_ctx.showClear ? (openBlock(), createBlock(_component_CloseCircleFilled, {
    key: 0,
    onClick: withModifiers(_ctx.clear, ["stop"])
  }, null, 8 /* PROPS */, ["onClick"])) : renderSlot(_ctx.$slots, "suffix", {
    key: 1
  })], 34 /* CLASS, NEED_HYDRATION */)], 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_1);
}

script.render = render;
script.__file = "components/date-picker/rangeInput.vue";

export { script as default };
