import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import { defineComponent, computed, ref, watch, resolveComponent, openBlock, createBlock, withCtx, normalizeClass, normalizeStyle, renderSlot, createVNode } from 'vue';
import { isValid, format } from 'date-fns';
import { isNil, isEqual, isArray } from 'lodash-es';
import InputInner from '../input/inputInner.js';
import Popper from '../popper';
import useFormAdaptor from '../_util/use/useFormAdaptor';
import { useNormalModel } from '../_util/use/useModel';
import getPrefixCls from '../_util/getPrefixCls';
import { useTheme } from '../_theme/useTheme';
import { DateOutlined, SwapRightOutlined } from '../icon';
import { useLocale } from '../config-provider/useLocale';
import { COMMON_PROPS, RANGE_PROPS } from './const';
import { strictParse, isEmptyValue } from './helper';
import Calendars from './calendars.js';
import RangeInput from './rangeInput.js';
import { pickerFactory, PickerType } from './pickerHandler';
import { useDisable } from './use';

function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
const prefixCls = getPrefixCls('date-picker');
const datePickerProps = _objectSpread(_objectSpread({
  open: {
    type: Boolean,
    default: false
  },
  disabled: {
    type: Boolean,
    default: false
  },
  clearable: {
    type: Boolean,
    default: false
  },
  placeholder: {
    type: [String, Array]
  },
  appendToContainer: {
    type: Boolean,
    default: true
  },
  getContainer: {
    type: Function
  },
  popperClass: [String, Array, Object],
  control: Boolean,
  shortcuts: Object,
  disabledDate: Function
}, COMMON_PROPS), RANGE_PROPS);
const useTmpSelectedDates = () => {
  const tmpSelectedDates = ref();
  const tmpSelectedDateChange = val => {
    tmpSelectedDates.value = val;
  };
  return {
    tmpSelectedDates,
    tmpSelectedDateChange
  };
};
const useInput = _ref => {
  let {
    props,
    visibleValue,
    picker,
    changeDateByInput
  } = _ref;
  const dateText = ref();
  const {
    innerDisabledDate
  } = useDisable(props);
  let cacheValidInputDate = '';
  const getFormatDate = () => {
    if (isEmptyValue(visibleValue.value)) {
      return '';
    }
    if (!picker.value.isRange) {
      if (isArray(visibleValue.value)) {
        return visibleValue.value.map(item => {
          return format(item, props.format || picker.value.format);
        }).join('; ');
      }
      return format(visibleValue.value, props.format || picker.value.format);
    }
    return '';
  };
  const resetDateText = () => {
    dateText.value = getFormatDate();
    cacheValidInputDate = dateText.value;
  };
  watch([visibleValue, () => props.format], resetDateText, {
    immediate: true
  });
  const handleDateInput = val => {
    dateText.value = val;
    const date = strictParse(val, props.format || picker.value.format, new Date());
    if (isValid(date) && !innerDisabledDate(date, props.format || picker.value.format)) {
      cacheValidInputDate = val;
      changeDateByInput(date.getTime());
    }
  };
  const handleDateInputBlur = () => {
    if (dateText.value !== cacheValidInputDate && cacheValidInputDate) {
      dateText.value = cacheValidInputDate;
    }
  };
  return {
    resetDateText,
    dateText,
    handleDateInput,
    handleDateInputBlur
  };
};
const usePlaceholder = (props, picker) => {
  const {
    t
  } = useLocale();
  const innerPlaceHolder = computed(() => {
    if (props.placeholder) {
      return props.placeholder;
    }
    const placeholderLang = picker.value.placeholderLang;
    if (Array.isArray(placeholderLang)) {
      return placeholderLang.map(item => t(item));
    }
    return t(placeholderLang);
  });
  const singlePlaceHolder = computed(() => {
    return Array.isArray(innerPlaceHolder.value) ? innerPlaceHolder.value[0] : innerPlaceHolder.value;
  });
  return {
    innerPlaceHolder,
    singlePlaceHolder
  };
};
var script = defineComponent({
  name: 'FDatePicker',
  components: {
    Calendars,
    InputInner,
    Popper,
    DateOutlined,
    RangeInput,
    SwapRightOutlined
  },
  props: datePickerProps,
  emits: ['update:modelValue', 'update:open', 'change', 'clear', 'blur', 'focus'],
  setup(props, _ref2) {
    let {
      emit,
      attrs
    } = _ref2;
    useTheme();
    const [isOpened, updatePopperOpen] = useNormalModel(props, emit, {
      prop: 'open'
    });
    const [currentValue, updateCurrentValue] = useNormalModel(props, emit);
    /**
     * props.format 是最终给用户展示的格式，不必和 picker.value.format 一致
     * picker.value.format 用于内部处理
     */
    const pickerRef = computed(() => {
      return pickerFactory(props.type);
    });
    const inputRefEl = ref();
    const inputRangeRefEL = ref();
    const calendarsRef = ref();
    const activeInputRefEL = computed(() => {
      if (pickerRef.value.isRange) {
        return inputRangeRefEL.value;
      }
      return inputRefEl.value;
    });
    const {
      validate,
      isError,
      isFormDisabled
    } = useFormAdaptor({
      valueType: computed(() => pickerRef.value.isRange ? 'array' : 'number'),
      forbidChildValidate: true
    });
    const innerDisabled = computed(() => props.disabled || isFormDisabled.value);
    const {
      innerPlaceHolder,
      singlePlaceHolder
    } = usePlaceholder(props, pickerRef);
    const {
      tmpSelectedDates,
      tmpSelectedDateChange
    } = useTmpSelectedDates();
    const visibleValue = computed(() => {
      if (isOpened.value) {
        return isNil(tmpSelectedDates.value) ? currentValue.value : tmpSelectedDates.value;
      }
      return currentValue.value;
    });
    const handleChange = val => {
      if (!isEqual(val, currentValue.value)) {
        updateCurrentValue(val);
        emit('change', val);
        validate('change');
      }
    };

    // 输入框里的变更，直接更新 currentValue
    const changeDateByInput = val => {
      tmpSelectedDateChange(null);
      handleChange(val);
    };
    const {
      resetDateText,
      dateText,
      handleDateInput,
      handleDateInputBlur
    } = useInput({
      props,
      visibleValue,
      changeDateByInput,
      picker: pickerRef
    });

    // 事件
    const clear = () => {
      const initValue = pickerRef.value.isRange || pickerRef.value.name === PickerType.datemultiple ? [] : null;
      tmpSelectedDateChange(null);
      handleChange(initValue);
      emit('clear');
    };
    const changeDateBycalendars = val => {
      handleChange(val);
      // 选择完后重新聚焦
      activeInputRefEL.value.focus();
      updatePopperOpen(false);
    };
    const inputIsFocus = ref(false);
    const handleFocus = e => {
      // 防止重复聚焦
      if (!inputIsFocus.value) {
        inputIsFocus.value = true;
        emit('focus', e);
      }
    };
    let cacheEvent = null;
    const checkBlur = () => {
      if (!isOpened.value && cacheEvent) {
        emit('blur', cacheEvent);
        validate('blur');
        // 重置输入框内容
        resetDateText();
        cacheEvent = null;
        inputIsFocus.value = false;
      }
    };
    const handleBlur = e => {
      var _calendarsRef$value;
      cacheEvent = e;
      // 非弹窗内容点击导致的失焦，进行 blur 的校验
      // 兼容禁用状态，选择框不展示的情况
      if (!((_calendarsRef$value = calendarsRef.value) !== null && _calendarsRef$value !== void 0 && _calendarsRef$value.$el.contains(e.relatedTarget))) {
        if (isOpened.value) {
          updatePopperOpen(false);
        }
        checkBlur();
      }
    };
    watch(isOpened, () => {
      if (!isOpened.value) {
        // 重置临时输入
        tmpSelectedDateChange(null);
      }
    });
    const handlePopperVisible = val => {
      if (val === false) {
        checkBlur();
      }
    };
    return {
      prefixCls,
      isOpened,
      currentValue,
      visibleValue,
      isError,
      innerDisabled,
      dateText,
      handleDateInput,
      handleDateInputBlur: event => {
        handleDateInputBlur();
        handleBlur(event);
      },
      PickerType,
      pickerRef,
      changeDateByInput,
      clear,
      changeDateBycalendars,
      inputIsFocus,
      handleFocus,
      handleBlur,
      tmpSelectedDateChange,
      innerPlaceHolder,
      singlePlaceHolder,
      handlePopperVisible,
      inputRefEl,
      inputRangeRefEL,
      calendarsRef,
      attrs
    };
  }
});

function render(_ctx, _cache, $props, $setup, $data, $options) {
  const _component_SwapRightOutlined = resolveComponent("SwapRightOutlined");
  const _component_DateOutlined = resolveComponent("DateOutlined");
  const _component_RangeInput = resolveComponent("RangeInput");
  const _component_InputInner = resolveComponent("InputInner");
  const _component_calendars = resolveComponent("calendars");
  const _component_Popper = resolveComponent("Popper");
  return openBlock(), createBlock(_component_Popper, {
    modelValue: _ctx.isOpened,
    "onUpdate:modelValue": [_cache[0] || (_cache[0] = $event => _ctx.isOpened = $event), _ctx.handlePopperVisible],
    disabled: _ctx.innerDisabled,
    appendToContainer: _ctx.appendToContainer,
    getContainer: _ctx.getContainer,
    popperClass: [_ctx.popperClass, `${_ctx.prefixCls}-popper`],
    trigger: "click",
    hideAfter: 0,
    placement: "bottom-start",
    offset: 4,
    onlyShowTrigger: ""
  }, {
    trigger: withCtx(() => [_ctx.pickerRef.isRange ? (openBlock(), createBlock(_component_RangeInput, {
      key: 0,
      ref: "inputRangeRefEL",
      format: _ctx.format || _ctx.pickerRef.format,
      selectedDates: _ctx.visibleValue,
      placeholder: _ctx.innerPlaceHolder,
      clearable: _ctx.clearable,
      disabled: _ctx.innerDisabled,
      innerIsFocus: _ctx.inputIsFocus,
      innerIsError: _ctx.isError,
      class: normalizeClass(_ctx.attrs.class),
      style: normalizeStyle(_ctx.attrs.style),
      changeSelectedDates: _ctx.changeDateByInput,
      maxRange: _ctx.maxRange,
      onFocus: _ctx.handleFocus,
      onBlur: _ctx.handleBlur,
      onClear: _ctx.clear
    }, {
      separator: withCtx(() => [_ctx.$slots.separator ? renderSlot(_ctx.$slots, "separator", {
        key: 0
      }) : (openBlock(), createBlock(_component_SwapRightOutlined, {
        key: 1
      }))]),
      suffix: withCtx(() => [_ctx.$slots.suffixIcon ? renderSlot(_ctx.$slots, "suffixIcon", {
        key: 0
      }) : (openBlock(), createBlock(_component_DateOutlined, {
        key: 1
      }))]),
      _: 3 /* FORWARDED */
    }, 8 /* PROPS */, ["format", "selectedDates", "placeholder", "clearable", "disabled", "innerIsFocus", "innerIsError", "class", "style", "changeSelectedDates", "maxRange", "onFocus", "onBlur", "onClear"])) : (openBlock(), createBlock(_component_InputInner, {
      key: 1,
      ref: "inputRefEl",
      modelValue: _ctx.dateText,
      placeholder: _ctx.singlePlaceHolder,
      disabled: _ctx.innerDisabled,
      canEdit: _ctx.pickerRef.name !== _ctx.PickerType.datemultiple,
      clearable: _ctx.clearable,
      innerIsFocus: _ctx.inputIsFocus,
      innerIsError: _ctx.isError,
      class: normalizeClass(_ctx.attrs.class),
      style: normalizeStyle(_ctx.attrs.style),
      onFocus: _ctx.handleFocus,
      onInput: _ctx.handleDateInput,
      onBlur: _ctx.handleDateInputBlur,
      onClear: _ctx.clear
    }, {
      suffix: withCtx(() => [_ctx.$slots.suffixIcon ? renderSlot(_ctx.$slots, "suffixIcon", {
        key: 0
      }) : (openBlock(), createBlock(_component_DateOutlined, {
        key: 1
      }))]),
      _: 3 /* FORWARDED */
    }, 8 /* PROPS */, ["modelValue", "placeholder", "disabled", "canEdit", "clearable", "innerIsFocus", "innerIsError", "class", "style", "onFocus", "onInput", "onBlur", "onClear"]))]),
    default: withCtx(() => [createVNode(_component_calendars, {
      ref: "calendarsRef",
      visible: _ctx.isOpened,
      modelValue: _ctx.currentValue,
      type: _ctx.type,
      control: _ctx.control,
      shortcuts: _ctx.shortcuts,
      minDate: _ctx.minDate,
      maxDate: _ctx.maxDate,
      maxRange: _ctx.maxRange,
      hourStep: _ctx.hourStep,
      minuteStep: _ctx.minuteStep,
      secondStep: _ctx.secondStep,
      disabledDate: _ctx.disabledDate,
      disabledTime: _ctx.disabledTime,
      defaultTime: _ctx.defaultTime,
      onChange: _ctx.changeDateBycalendars,
      onTmpSelectedDateChange: _ctx.tmpSelectedDateChange
    }, null, 8 /* PROPS */, ["visible", "modelValue", "type", "control", "shortcuts", "minDate", "maxDate", "maxRange", "hourStep", "minuteStep", "secondStep", "disabledDate", "disabledTime", "defaultTime", "onChange", "onTmpSelectedDateChange"])]),
    _: 3 /* FORWARDED */
  }, 8 /* PROPS */, ["modelValue", "disabled", "appendToContainer", "getContainer", "popperClass", "onUpdate:modelValue"]);
}

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

export { datePickerProps, script as default };
