import { defineComponent, computed, ref, watch, resolveComponent, openBlock, createBlock, withCtx, normalizeClass, normalizeStyle, createSlots, createVNode, createCommentVNode, createElementVNode, withModifiers, createElementBlock, renderSlot, createTextVNode, toDisplayString } from 'vue';
import { UPDATE_MODEL_EVENT } from '../_util/constants';
import useFormAdaptor from '../_util/use/useFormAdaptor';
import getPrefixCls from '../_util/getPrefixCls';
import { useNormalModel } from '../_util/use/useModel';
import { useTheme } from '../_theme/useTheme';
import InputInner from '../input/inputInner.js';
import { ClockCircleOutlined } from '../icon';
import Popper from '../popper';
import FButton from '../button';
import { useLocale } from '../config-provider/useLocale';
import TimeSelect from './time-select.js';

const prefixCls = getPrefixCls('time-picker');

// TODO 支持 12 小时制
function formatTimeCell(data) {
  return `${data}`.padStart(2, '0');
}
const getCurrentTime = format => {
  const date = new Date();
  return [format.indexOf('H') !== -1 && formatTimeCell(date.getHours()), format.indexOf('m') !== -1 && formatTimeCell(date.getMinutes()), format.indexOf('s') !== -1 && formatTimeCell(date.getSeconds())].filter(Boolean).join(':');
};
function validator(val, cellFormat, max) {
  if (!val) {
    return false;
  }
  if (val.length > 3 || !/^\d{1,2}$/.test(val) || Number(val) > max || val.length < cellFormat.length) {
    return false;
  }
  return true;
}
function validateTime(data, format) {
  const times = data.split(':');
  const cellFormats = format.split(':');
  if (times.length !== cellFormats.length) {
    return false;
  }
  for (let i = 0; i < cellFormats.length; ++i) {
    const cellFormat = cellFormats[i];
    if (/[Hh]/.test(cellFormat)) {
      if (!validator(times.shift(), cellFormat, 23)) {
        return false;
      }
    } else {
      if (!validator(times.shift(), cellFormat, 59)) {
        return false;
      }
    }
  }
  return true;
}
const timePickerProps = {
  modelValue: {
    // timePicker 目前仅支持string
    type: String,
    default: ''
  },
  open: {
    type: Boolean,
    default: false
  },
  appendToContainer: {
    type: Boolean,
    default: true
  },
  getContainer: {
    type: Function
  },
  placeholder: {
    type: String,
    default: ''
  },
  // FEATURE 下个版本实现
  isRange: {
    type: Boolean,
    default: false
  },
  disabled: {
    type: Boolean,
    default: false
  },
  clearable: {
    type: Boolean,
    default: true
  },
  format: {
    type: String,
    default: 'HH:mm:ss'
  },
  hourStep: {
    type: Number,
    default: 1
  },
  minuteStep: {
    type: Number,
    default: 1
  },
  secondStep: {
    type: Number,
    default: 1
  },
  disabledHours: Function,
  disabledMinutes: Function,
  disabledSeconds: Function,
  control: {
    type: Boolean,
    default: true
  },
  showSuffix: {
    type: Boolean,
    default: true
  },
  inputClass: {
    type: [String, Object, Array]
  }
};
function useOpen(props, emit) {
  const [isOpened, updateCurrentValue] = useNormalModel(props, emit, {
    prop: 'open'
  });
  const closePopper = () => {
    updateCurrentValue(false);
  };
  return {
    isOpened,
    closePopper
  };
}
var script = defineComponent({
  name: 'FTimePicker',
  components: {
    TimeSelect,
    InputInner,
    Popper,
    ClockCircleOutlined,
    FButton
  },
  props: timePickerProps,
  emits: [UPDATE_MODEL_EVENT, 'update:open', 'change', 'blur', 'focus'],
  setup(props, _ref) {
    let {
      emit,
      attrs
    } = _ref;
    useTheme();
    const {
      validate,
      isError,
      isFormDisabled
    } = useFormAdaptor({
      forbidChildValidate: true
    });
    const innerDisabled = computed(() => props.disabled || isFormDisabled.value);
    const [currentValue, updateCurrentValue] = useNormalModel(props, emit);
    const {
      isOpened,
      closePopper
    } = useOpen(props, emit);
    const classes = computed(() => [prefixCls, (isFormDisabled.value || props.disabled) && 'is-disabled', props.inputClass].filter(Boolean));
    const showControl = computed(() => props.control);
    const showNowShortcut = computed(() => {
      // format 中的 token 需要与 TimeSelect 中的 canSelectHours 保持一致
      if (props.format.includes('H') && props.hourStep !== 1) {
        return false;
      }
      if (props.format.includes('m') && props.minuteStep !== 1) {
        return false;
      }
      if (props.format.includes('s') && props.secondStep !== 1) {
        return false;
      }
      return true;
    });

    // 临时的值
    const tempValue = ref();
    const {
      t
    } = useLocale();
    const inputPlaceholder = computed(() => props.placeholder || t('timePicker.placeholder'));
    const activeTime = ref();
    const changeTime = val => {
      tempValue.value = '';
      activeTime.value = val;
    };
    const setCurrentValue = val => {
      if (val !== currentValue.value) {
        tempValue.value = '';
        updateCurrentValue(val);
        emit('change', val);
        validate('change');
        activeTime.value = val;
      }
    };
    // 获取 实例
    const timeSelectRef = ref();

    // 解耦 与设置值的方法分开
    const clear = () => {
      tempValue.value = '';
      updateCurrentValue('');
      activeTime.value = '';
      emit('change', '');
      validate('change');
      // 重置时间
      timeSelectRef.value.resetTime();
    };
    watch(isOpened, () => {
      // 关闭将选中的数据赋值，因此确认按钮只用关闭弹窗即可
      if (!isOpened.value && activeTime.value) {
        setCurrentValue(activeTime.value);
      }
    });
    const handleInput = val => {
      tempValue.value = val;
      if (validateTime(val, props.format)) {
        setCurrentValue(val);
      }
    };
    const setCurrentTime = () => {
      setCurrentValue(getCurrentTime(props.format));
      closePopper();
    };
    const confirmChangeTime = () => {
      closePopper();
    };

    // 输入框展示的值
    const displayValue = computed(() => {
      // 目前没有范围选择
      if (props.isRange) {
        return currentValue.value || [];
      }
      return tempValue.value || activeTime.value || currentValue.value || '';
    });
    const handleBlur = event => {
      closePopper();
      emit('blur', event);
      validate('blur');

      // 重置手动输入值
      tempValue.value = null;
    };
    return {
      prefixCls,
      isError,
      innerDisabled,
      classes,
      displayValue,
      isOpened,
      currentValue,
      tempValue,
      handleInput,
      handleBlur,
      clear,
      changeTime,
      showControl,
      showNowShortcut,
      setCurrentTime,
      confirmChangeTime,
      activeTime,
      inputPlaceholder,
      t,
      attrs,
      timeSelectRef
    };
  }
});

function render(_ctx, _cache, $props, $setup, $data, $options) {
  const _component_ClockCircleOutlined = resolveComponent("ClockCircleOutlined");
  const _component_InputInner = resolveComponent("InputInner");
  const _component_TimeSelect = resolveComponent("TimeSelect");
  const _component_FButton = resolveComponent("FButton");
  const _component_Popper = resolveComponent("Popper");
  return openBlock(), createBlock(_component_Popper, {
    modelValue: _ctx.isOpened,
    "onUpdate:modelValue": _cache[4] || (_cache[4] = $event => _ctx.isOpened = $event),
    trigger: "click",
    placement: "bottom-start",
    popperClass: `${_ctx.prefixCls}-popper`,
    disabled: _ctx.innerDisabled,
    appendToContainer: _ctx.appendToContainer,
    getContainer: _ctx.getContainer,
    hideAfter: 0,
    offset: 4,
    onlyShowTrigger: ""
  }, {
    trigger: withCtx(() => [!_ctx.isRange ? (openBlock(), createBlock(_component_InputInner, {
      key: 0,
      class: normalizeClass([_ctx.attrs.class, _ctx.classes]),
      style: normalizeStyle(_ctx.attrs.style),
      modelValue: _ctx.displayValue,
      placeholder: _ctx.inputPlaceholder,
      disabled: _ctx.innerDisabled,
      clearable: _ctx.clearable,
      innerIsError: _ctx.isError,
      onClear: _ctx.clear,
      onInput: _ctx.handleInput,
      onFocus: _cache[0] || (_cache[0] = event => _ctx.$emit('focus', event)),
      onBlur: _ctx.handleBlur
    }, createSlots({
      _: 2 /* DYNAMIC */
    }, [_ctx.showSuffix ? {
      name: "suffix",
      fn: withCtx(() => [createVNode(_component_ClockCircleOutlined)]),
      key: "0"
    } : undefined]), 1032 /* PROPS, DYNAMIC_SLOTS */, ["class", "style", "modelValue", "placeholder", "disabled", "clearable", "innerIsError", "onClear", "onInput", "onBlur"])) : createCommentVNode("v-if", true)]),
    default: withCtx(() => [createElementVNode("div", {
      class: normalizeClass(`${_ctx.prefixCls}-dropdown`),
      onMousedown: _cache[3] || (_cache[3] = withModifiers(() => {}, ["prevent"]))
    }, [createVNode(_component_TimeSelect, {
      ref: "timeSelectRef",
      visible: _ctx.isOpened,
      modelValue: _ctx.currentValue,
      format: _ctx.format,
      "hour-step": _ctx.hourStep,
      "minute-step": _ctx.minuteStep,
      "second-step": _ctx.secondStep,
      "disabled-hours": _ctx.disabledHours,
      "disabled-minutes": _ctx.disabledMinutes,
      "disabled-seconds": _ctx.disabledSeconds,
      onChange: _ctx.changeTime
    }, null, 8 /* PROPS */, ["visible", "modelValue", "format", "hour-step", "minute-step", "second-step", "disabled-hours", "disabled-minutes", "disabled-seconds", "onChange"]), _ctx.showControl || _ctx.$slots.addon ? (openBlock(), createElementBlock("div", {
      key: 0,
      class: normalizeClass(`${_ctx.prefixCls}-addon`)
    }, [renderSlot(_ctx.$slots, "addon", {
      activeTime: _ctx.activeTime
    }, () => [createElementVNode("div", {
      class: normalizeClass(`${_ctx.prefixCls}-addon-inner`)
    }, [_ctx.showNowShortcut ? (openBlock(), createBlock(_component_FButton, {
      key: 0,
      type: "link",
      size: "small",
      onMousedown: _cache[1] || (_cache[1] = withModifiers(() => {}, ["prevent"])),
      onClick: _ctx.setCurrentTime
    }, {
      default: withCtx(() => [createTextVNode(toDisplayString(_ctx.t('timePicker.now')), 1 /* TEXT */)]),
      _: 1 /* STABLE */
    }, 8 /* PROPS */, ["onClick"])) : createCommentVNode("v-if", true), createVNode(_component_FButton, {
      type: "primary",
      size: "small",
      onMousedown: _cache[2] || (_cache[2] = withModifiers(() => {}, ["prevent"])),
      onClick: _ctx.confirmChangeTime
    }, {
      default: withCtx(() => [createTextVNode(toDisplayString(_ctx.t('timePicker.confirm')), 1 /* TEXT */)]),
      _: 1 /* STABLE */
    }, 8 /* PROPS */, ["onClick"])], 2 /* CLASS */)])], 2 /* CLASS */)) : createCommentVNode("v-if", true)], 34 /* CLASS, NEED_HYDRATION */)]),
    _: 3 /* FORWARDED */
  }, 8 /* PROPS */, ["modelValue", "popperClass", "disabled", "appendToContainer", "getContainer"]);
}

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

export { script as default, timePickerProps };
