import { defineComponent, inject, ref, watch, nextTick, computed, provide } from 'vue';
import dayjs from 'dayjs';
import isEqual from 'lodash/isEqual';
import '../../../../hooks/index.mjs';
import '../../../../directives/index.mjs';
import '../../../../tokens/index.mjs';
import { ElInput } from '../../../input/index.mjs';
import { ElIcon } from '../../../icon/index.mjs';
import _Popper from '../../../popper/index.mjs';
import { EVENT_CODE } from '../../../../utils/aria.mjs';
import { isEmpty, useGlobalConfig } from '../../../../utils/util.mjs';
import { ArrowRight, ArrowLeft, Clock, Calendar } from '@element-plus/icons-vue';
import { timePickerDefaultProps } from './props.mjs';
import ClickOutside from '../../../../directives/click-outside/index.mjs';
import { useLocale } from '../../../../hooks/use-locale/index.mjs';
import { elFormKey, elFormItemKey } from '../../../../tokens/form.mjs';
import { Effect } from '../../../popper/src/use-popper/defaults.mjs';

const dateEquals = function(a, b) {
  const aIsDate = a instanceof Date;
  const bIsDate = b instanceof Date;
  if (aIsDate && bIsDate) {
    return a.getTime() === b.getTime();
  }
  if (!aIsDate && !bIsDate) {
    return a === b;
  }
  return false;
};
const valueEquals = function(a, b) {
  const aIsArray = a instanceof Array;
  const bIsArray = b instanceof Array;
  if (aIsArray && bIsArray) {
    if (a.length !== b.length) {
      return false;
    }
    return a.every((item, index) => dateEquals(item, b[index]));
  }
  if (!aIsArray && !bIsArray) {
    return dateEquals(a, b);
  }
  return false;
};
const parser = function(date, format, lang) {
  const day = isEmpty(format) ? dayjs(date).locale(lang) : dayjs(date, format).locale(lang);
  return day.isValid() ? day : void 0;
};
const formatter = function(date, format, lang) {
  return isEmpty(format) ? date : dayjs(date).locale(lang).format(format);
};
var script = defineComponent({
  name: "Picker",
  components: {
    ElInput,
    ElPopper: _Popper,
    ElIcon,
    ArrowRight,
    ArrowLeft
  },
  directives: { clickoutside: ClickOutside },
  props: timePickerDefaultProps,
  emits: [
    "update:modelValue",
    "change",
    "focus",
    "blur",
    "calendar-change",
    "decrease",
    "increase"
  ],
  setup(props, ctx) {
    const ELEMENT = useGlobalConfig();
    const { lang } = useLocale();
    const elForm = inject(elFormKey, {});
    const elFormItem = inject(elFormItemKey, {});
    const elPopperOptions = inject("ElPopperOptions", {});
    const refPopper = ref(null);
    const pickerVisible = ref(false);
    const pickerActualVisible = ref(false);
    const valueOnOpen = ref(null);
    watch(pickerVisible, (val) => {
      var _a;
      if (!val) {
        userInput.value = null;
        nextTick(() => {
          emitChange(props.modelValue);
        });
        ctx.emit("blur");
        blurInput();
        props.validateEvent && ((_a = elFormItem.validate) == null ? void 0 : _a.call(elFormItem, "blur"));
      } else {
        valueOnOpen.value = props.modelValue;
      }
    });
    const emitChange = (val, isClear) => {
      var _a;
      if (isClear || !valueEquals(val, valueOnOpen.value)) {
        ctx.emit("change", val);
        props.validateEvent && ((_a = elFormItem.validate) == null ? void 0 : _a.call(elFormItem, "change"));
      }
    };
    const emitInput = (val) => {
      if (!valueEquals(props.modelValue, val)) {
        let formatValue;
        if (Array.isArray(val)) {
          formatValue = val.map((_) => formatter(_, props.valueFormat, lang.value));
        } else if (val) {
          formatValue = formatter(val, props.valueFormat, lang.value);
        }
        ctx.emit("update:modelValue", val ? formatValue : val, lang.value);
      }
    };
    const refInput = computed(() => {
      if (refPopper.value.triggerRef) {
        const _r = isRangeInput.value ? refPopper.value.triggerRef : refPopper.value.triggerRef.$el;
        return [].slice.call(_r.querySelectorAll("input"));
      }
      return [];
    });
    const setSelectionRange = (start, end, pos) => {
      const _inputs = refInput.value;
      if (!_inputs.length)
        return;
      if (!pos || pos === "min") {
        _inputs[0].setSelectionRange(start, end);
        _inputs[0].focus();
      } else if (pos === "max") {
        _inputs[1].setSelectionRange(start, end);
        _inputs[1].focus();
      }
    };
    const onPick = (date = "", visible = false) => {
      pickerVisible.value = visible;
      let result;
      if (Array.isArray(date)) {
        result = date.map((_) => _.toDate());
      } else {
        result = date ? date.toDate() : date;
      }
      userInput.value = null;
      emitInput(result);
    };
    const handleFocus = (e) => {
      if (props.readonly || pickerDisabled.value || pickerVisible.value)
        return;
      pickerVisible.value = true;
      ctx.emit("focus", e);
    };
    const handleBlur = () => {
      pickerVisible.value = false;
      blurInput();
    };
    const pickerDisabled = computed(() => {
      return props.disabled || elForm.disabled;
    });
    const parsedValue = computed(() => {
      let result;
      if (valueIsEmpty.value) {
        if (pickerOptions.value.getDefaultValue) {
          result = pickerOptions.value.getDefaultValue();
        }
      } else {
        if (Array.isArray(props.modelValue)) {
          result = props.modelValue.map((_) => parser(_, props.valueFormat, lang.value));
        } else {
          result = parser(props.modelValue, props.valueFormat, lang.value);
        }
      }
      if (pickerOptions.value.getRangeAvailableTime) {
        const availableResult = pickerOptions.value.getRangeAvailableTime(result);
        if (!isEqual(availableResult, result)) {
          result = availableResult;
          emitInput(Array.isArray(result) ? result.map((_) => _.toDate()) : result.toDate());
        }
      }
      if (Array.isArray(result) && result.some((_) => !_)) {
        result = [];
      }
      return result;
    });
    const displayValue = computed(() => {
      if (!pickerOptions.value.panelReady)
        return;
      const formattedValue = formatDayjsToString(parsedValue.value);
      if (Array.isArray(userInput.value)) {
        return [
          userInput.value[0] || formattedValue && formattedValue[0] || "",
          userInput.value[1] || formattedValue && formattedValue[1] || ""
        ];
      } else if (userInput.value !== null) {
        return userInput.value;
      }
      if (!isTimePicker.value && valueIsEmpty.value)
        return;
      if (!pickerVisible.value && valueIsEmpty.value)
        return;
      if (formattedValue) {
        return isDatesPicker.value ? formattedValue.join(", ") : formattedValue;
      }
      return "";
    });
    const isTimeLikePicker = computed(() => props.type.includes("time"));
    const isTimePicker = computed(() => props.type.startsWith("time"));
    const isDatesPicker = computed(() => props.type === "dates");
    const triggerIcon = computed(() => props.prefixIcon || (isTimeLikePicker.value ? Clock : Calendar));
    const showClose = ref(false);
    const onClearIconClick = (event) => {
      if (props.readonly || pickerDisabled.value)
        return;
      if (showClose.value) {
        event.stopPropagation();
        emitInput(null);
        emitChange(null, true);
        showClose.value = false;
        pickerVisible.value = false;
        pickerOptions.value.handleClear && pickerOptions.value.handleClear();
      }
    };
    const valueIsEmpty = computed(() => {
      return !props.modelValue || Array.isArray(props.modelValue) && !props.modelValue.length;
    });
    const onMouseEnter = () => {
      if (props.readonly || pickerDisabled.value)
        return;
      if (!valueIsEmpty.value && props.clearable) {
        showClose.value = true;
      }
    };
    const onMouseLeave = () => {
      showClose.value = false;
    };
    const isRangeInput = computed(() => {
      return props.type.indexOf("range") > -1;
    });
    const pickerSize = computed(() => {
      return props.size || elFormItem.size || ELEMENT.size;
    });
    const popperPaneRef = computed(() => {
      var _a;
      return (_a = refPopper.value) == null ? void 0 : _a.popperRef;
    });
    const onClickOutside = () => {
      if (!pickerVisible.value)
        return;
      pickerVisible.value = false;
    };
    const userInput = ref(null);
    const handleChange = () => {
      if (userInput.value) {
        const value = parseUserInputToDayjs(displayValue.value);
        if (value) {
          if (isValidValue(value)) {
            emitInput(Array.isArray(value) ? value.map((_) => _.toDate()) : value.toDate());
            userInput.value = null;
          }
        }
      }
      if (userInput.value === "") {
        emitInput(null);
        emitChange(null);
        userInput.value = null;
      }
    };
    const blurInput = () => {
      refInput.value.forEach((input) => input.blur());
    };
    const parseUserInputToDayjs = (value) => {
      if (!value)
        return null;
      return pickerOptions.value.parseUserInput(value);
    };
    const formatDayjsToString = (value) => {
      if (!value)
        return null;
      return pickerOptions.value.formatToString(value);
    };
    const isValidValue = (value) => {
      return pickerOptions.value.isValidValue(value);
    };
    const handleKeydown = (event) => {
      const code = event.code;
      if (code === EVENT_CODE.esc) {
        pickerVisible.value = false;
        event.stopPropagation();
        return;
      }
      if (code === EVENT_CODE.tab) {
        if (!isRangeInput.value) {
          handleChange();
          pickerVisible.value = false;
          event.stopPropagation();
        } else {
          setTimeout(() => {
            if (refInput.value.indexOf(document.activeElement) === -1) {
              pickerVisible.value = false;
              blurInput();
            }
          }, 0);
        }
        return;
      }
      if (code === EVENT_CODE.enter || code === EVENT_CODE.numpadEnter) {
        if (userInput.value === null || userInput.value === "" || isValidValue(parseUserInputToDayjs(displayValue.value))) {
          handleChange();
          pickerVisible.value = false;
        }
        event.stopPropagation();
        return;
      }
      if (userInput.value) {
        event.stopPropagation();
        return;
      }
      if (pickerOptions.value.handleKeydown) {
        pickerOptions.value.handleKeydown(event);
      }
    };
    const onUserInput = (e) => {
      userInput.value = e;
    };
    const handleStartInput = (event) => {
      if (userInput.value) {
        userInput.value = [event.target.value, userInput.value[1]];
      } else {
        userInput.value = [event.target.value, null];
      }
    };
    const handleEndInput = (event) => {
      if (userInput.value) {
        userInput.value = [userInput.value[0], event.target.value];
      } else {
        userInput.value = [null, event.target.value];
      }
    };
    const handleStartChange = () => {
      const value = parseUserInputToDayjs(userInput.value && userInput.value[0]);
      if (value && value.isValid()) {
        userInput.value = [formatDayjsToString(value), displayValue.value[1]];
        const newValue = [value, parsedValue.value && parsedValue.value[1]];
        if (isValidValue(newValue)) {
          emitInput(newValue);
          userInput.value = null;
        }
      }
    };
    const handleEndChange = () => {
      const value = parseUserInputToDayjs(userInput.value && userInput.value[1]);
      if (value && value.isValid()) {
        userInput.value = [displayValue.value[0], formatDayjsToString(value)];
        const newValue = [parsedValue.value && parsedValue.value[0], value];
        if (isValidValue(newValue)) {
          emitInput(newValue);
          userInput.value = null;
        }
      }
    };
    const pickerOptions = ref({});
    const onSetPickerOption = (e) => {
      pickerOptions.value[e[0]] = e[1];
      pickerOptions.value.panelReady = true;
    };
    const onCalendarChange = (e) => {
      ctx.emit("calendar-change", e);
    };
    const decrease = () => {
      ctx.emit("decrease");
    };
    const increase = () => {
      ctx.emit("increase");
    };
    provide("EP_PICKER_BASE", {
      props
    });
    return {
      Effect,
      elPopperOptions,
      isDatesPicker,
      handleEndChange,
      handleStartChange,
      handleStartInput,
      handleEndInput,
      onUserInput,
      handleChange,
      handleKeydown,
      popperPaneRef,
      onClickOutside,
      pickerSize,
      isRangeInput,
      onMouseLeave,
      onMouseEnter,
      onClearIconClick,
      showClose,
      triggerIcon,
      onPick,
      handleFocus,
      handleBlur,
      pickerVisible,
      pickerActualVisible,
      displayValue,
      parsedValue,
      setSelectionRange,
      refPopper,
      pickerDisabled,
      onSetPickerOption,
      onCalendarChange,
      step: props.step,
      decrease,
      increase
    };
  }
});

export { script as default };
//# sourceMappingURL=picker.vue_vue_type_script_lang.mjs.map
