import { defineComponent, ref, inject, computed, watch, provide, createBlock, openBlock, unref, normalizeClass, createSlots, withCtx, createVNode, renderSlot } from "vue";
import { defaultSize } from "../_utils/global.mjs";
import { OInput } from "../input/index.mjs";
import { number2string, isValidNumber, string2number, correctValue } from "./input-number.mjs";
import { isUndefined, isFunction, isNumber } from "../_utils/is.mjs";
import { inputNumberProps } from "./types.mjs";
import _sfc_main$1 from "./NumberControl.vue.mjs";
import { formItemInjectKey } from "../form/provide.mjs";
import { innerComponentInjectKey } from "../_components/provide.mjs";
const _sfc_main = /* @__PURE__ */ defineComponent({
  __name: "OInputNumber",
  props: inputNumberProps,
  emits: ["update:modelValue", "change", "input", "blur", "focus", "clear", "pressEnter", "plus", "minus"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emits = __emit;
    const inputValue = ref(number2string(props.modelValue ?? props.defaultValue));
    const realValue = ref(props.modelValue ?? props.defaultValue ?? NaN);
    let lastValue = realValue.value;
    const formItemInjection = inject(formItemInjectKey, null);
    const color = computed(() => {
      var _a;
      if (formItemInjection == null ? void 0 : formItemInjection.fieldResult.value) {
        return ((_a = formItemInjection == null ? void 0 : formItemInjection.fieldResult.value) == null ? void 0 : _a.type) || void 0;
      } else {
        return props.color;
      }
    });
    watch(
      () => props.modelValue,
      (val) => {
        if (realValue.value !== val) {
          inputValue.value = number2string(val);
          realValue.value = val ?? 0;
          lastValue = realValue.value;
        }
      }
    );
    const validate = (value) => {
      const val = string2number(value);
      let valid = isValidNumber(val, props.min, props.max);
      if (valid) {
        valid = isFunction(props.validate) ? props.validate(val) : true;
      }
      return valid;
    };
    const valueOnInvalidChange = (_, last) => {
      return last;
    };
    const emitChange = () => {
      var _a, _b;
      if (realValue.value !== lastValue) {
        emits("change", realValue.value);
        lastValue = realValue.value;
        (_b = formItemInjection == null ? void 0 : (_a = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _b.call(_a);
      }
    };
    const emitUpdateValue = () => {
      emits("update:modelValue", realValue.value);
    };
    const onInput = (evt) => {
      var _a, _b;
      emits("input", evt);
      (_b = formItemInjection == null ? void 0 : (_a = formItemInjection.fieldHandlers).onInput) == null ? void 0 : _b.call(_a);
    };
    const onFocus = (evt) => {
      var _a, _b;
      emits("focus", evt);
      (_b = formItemInjection == null ? void 0 : (_a = formItemInjection.fieldHandlers).onFocus) == null ? void 0 : _b.call(_a);
    };
    const onBlur = (evt) => {
      var _a, _b;
      emits("blur", evt);
      (_b = formItemInjection == null ? void 0 : (_a = formItemInjection.fieldHandlers).onBlur) == null ? void 0 : _b.call(_a);
    };
    const onPressEnter = (evt) => {
      emits("pressEnter", evt);
    };
    const onChange = (value) => {
      realValue.value = string2number(value);
      if (isNaN(realValue.value) && isNumber(props.clearValue)) {
        realValue.value = props.clearValue;
        emitUpdateValue();
      }
      inputValue.value = number2string(realValue.value);
      emitChange();
    };
    const onUpdateModelValue = (value) => {
      inputValue.value = value;
      realValue.value = string2number(value);
      emitUpdateValue();
    };
    const addable = computed(() => {
      if (props.disabled) {
        return false;
      }
      if (!isUndefined(props.max) && props.max <= realValue.value) {
        return false;
      }
      return true;
    });
    const reducible = computed(() => {
      if (props.disabled) {
        return false;
      }
      if (!isUndefined(props.min) && props.min >= realValue.value) {
        return false;
      }
      return true;
    });
    const onControlEvent = (type, e) => {
      if (props.disabled) {
        return;
      }
      let v = Number.isNaN(realValue.value) ? 0 : realValue.value;
      if (type === "plus") {
        v += props.step;
      } else if (type === "minus") {
        v -= props.step;
      }
      v = correctValue(v, lastValue, props.min, props.max);
      realValue.value = v;
      inputValue.value = number2string(v);
      emitUpdateValue();
      emitChange();
      if (type === "plus") {
        emits("plus", v, e);
      } else if (type === "minus") {
        emits("minus", v, e);
      }
    };
    provide(innerComponentInjectKey, {
      isInnerInput: true
    });
    return (_ctx, _cache) => {
      return openBlock(), createBlock(unref(OInput), {
        "model-value": inputValue.value,
        class: normalizeClass(["o-input-number", [props.autoWidth ? "" : `o-input-number-size-${props.size || unref(defaultSize)}`]]),
        validate,
        valueOnInvalidChange,
        size: props.size,
        placeholder: props.placeholder,
        color: color.value,
        variant: props.variant,
        round: props.round,
        disabled: props.disabled,
        readonly: props.readonly,
        clearable: props.clearable,
        "auto-width": props.autoWidth,
        format: props.format,
        "input-id": props.inputId,
        type: "text",
        onInput,
        onBlur,
        onFocus,
        onPressEnter,
        onChange,
        "onUpdate:modelValue": onUpdateModelValue
      }, createSlots({
        _: 2
        /* DYNAMIC */
      }, [
        ["both", "left"].includes(props.controls) ? {
          name: "prepend",
          fn: withCtx(() => [
            createVNode(_sfc_main$1, {
              class: normalizeClass({ "o-input-control-left": props.controls === "both" }),
              type: props.controls === "left" ? "both" : "minus",
              addable: addable.value,
              reducible: reducible.value,
              onMinus: _cache[0] || (_cache[0] = (e) => onControlEvent("minus", e)),
              onPlus: _cache[1] || (_cache[1] = (e) => onControlEvent("plus", e))
            }, {
              plus: withCtx(() => [
                renderSlot(_ctx.$slots, "plus")
              ]),
              minus: withCtx(() => [
                renderSlot(_ctx.$slots, "minus")
              ]),
              _: 3
              /* FORWARDED */
            }, 8, ["class", "type", "addable", "reducible"])
          ]),
          key: "0"
        } : void 0,
        ["both", "right"].includes(props.controls) ? {
          name: "append",
          fn: withCtx(() => [
            createVNode(_sfc_main$1, {
              class: normalizeClass({ "o-input-control-right": props.controls === "both" }),
              type: props.controls === "right" ? "both" : "plus",
              addable: addable.value,
              reducible: reducible.value,
              onMinus: _cache[2] || (_cache[2] = (e) => onControlEvent("minus", e)),
              onPlus: _cache[3] || (_cache[3] = (e) => onControlEvent("plus", e))
            }, {
              plus: withCtx(() => [
                renderSlot(_ctx.$slots, "plus")
              ]),
              minus: withCtx(() => [
                renderSlot(_ctx.$slots, "minus")
              ]),
              _: 3
              /* FORWARDED */
            }, 8, ["class", "type", "addable", "reducible"])
          ]),
          key: "1"
        } : void 0,
        _ctx.$slots.prefix ? {
          name: "prefix",
          fn: withCtx(() => [
            renderSlot(_ctx.$slots, "prefix")
          ]),
          key: "2"
        } : void 0,
        _ctx.$slots.suffix ? {
          name: "suffix",
          fn: withCtx(() => [
            renderSlot(_ctx.$slots, "suffix")
          ]),
          key: "3"
        } : void 0
      ]), 1032, ["model-value", "class", "size", "placeholder", "color", "variant", "round", "disabled", "readonly", "clearable", "auto-width", "format", "input-id"]);
    };
  }
});
export {
  _sfc_main as default
};
