import { defineComponent, computed, shallowRef, nextTick, getCurrentInstance, watch, createVNode, watchEffect } from 'vue';
import '../../../utils/index.mjs';
import { useInjectFormItemContext, FormItemInputContext } from '../../form/src/FormItemContext.mjs';
import useConfigInject from '../../config-provider/src/hooks/useConfigInject.mjs';
import '../../config-provider/index.mjs';
import useStyle from '../style/index.mjs';
import { resolveOnChange, triggerFocus, fixControlledValue } from './util.mjs';
import ClearableLabeledInput from './ClearableLabeledInput.mjs';
import ResizableTextArea from './ResizableTextArea.mjs';
import { textAreaProps } from './props.mjs';
import { getMergedStatus, getStatusClassNames } from '../../../utils/statusUtils.mjs';
import { useInjectDisabled } from '../../config-provider/src/context/disabledContext.mjs';
import { omit } from '../../../utils/lang/omit.mjs';
import { classNames } from '../../../utils/dom/class.mjs';

function fixEmojiLength(value, maxLength) {
  return [...value || ""].slice(0, maxLength).join("");
}
function setTriggerValue(isCursorInEnd, preValue, triggerValue, maxLength) {
  let newTriggerValue = triggerValue;
  if (isCursorInEnd) {
    newTriggerValue = fixEmojiLength(triggerValue, maxLength);
  } else if ([...preValue || ""].length < triggerValue.length && [...triggerValue || ""].length > maxLength) {
    newTriggerValue = preValue;
  }
  return newTriggerValue;
}
var AInputTextArea = /* @__PURE__ */ defineComponent({
  compatConfig: {
    MODE: 3
  },
  name: "ATextarea",
  inheritAttrs: false,
  props: textAreaProps(),
  setup(props, {
    attrs,
    expose,
    emit
  }) {
    const formItemContext = useInjectFormItemContext();
    const formItemInputContext = FormItemInputContext.useInject();
    const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status));
    const stateValue = shallowRef(props.value === void 0 ? props.defaultValue : props.value);
    const resizableTextArea = shallowRef();
    const mergedValue = shallowRef("");
    const {
      prefixCls,
      size,
      direction
    } = useConfigInject("input", props);
    const [wrapSSR, hashId] = useStyle(prefixCls);
    const disabled = useInjectDisabled();
    const showCount = computed(() => {
      return props.showCount === "" || props.showCount || false;
    });
    const hasMaxLength = computed(() => Number(props.maxlength) > 0);
    const compositing = shallowRef(false);
    const oldCompositionValueRef = shallowRef();
    const oldSelectionStartRef = shallowRef(0);
    const onInternalCompositionStart = (e) => {
      compositing.value = true;
      oldCompositionValueRef.value = mergedValue.value;
      oldSelectionStartRef.value = e.currentTarget.selectionStart;
      emit("compositionstart", e);
    };
    const setValue = (value, callback) => {
      if (stateValue.value === value)
        return;
      if (props.value === void 0) {
        stateValue.value = value;
      } else {
        nextTick(() => {
          var _a, _b, _c;
          if (resizableTextArea.value.textArea.value !== mergedValue.value)
            (_c = (_a = resizableTextArea.value) == null ? void 0 : (_b = _a.instance).update) == null ? void 0 : _c.call(_b);
        });
      }
      nextTick(() => {
        callback && callback();
      });
    };
    const triggerChange = (e) => {
      emit("update:value", e.target.value);
      emit("change", e);
      emit("input", e);
      formItemContext.onFieldChange();
    };
    const onInternalCompositionEnd = (e) => {
      var _a;
      compositing.value = false;
      let triggerValue = e.currentTarget.value;
      if (hasMaxLength.value) {
        const isCursorInEnd = oldSelectionStartRef.value >= props.maxlength + 1 || oldSelectionStartRef.value === ((_a = oldCompositionValueRef.value) == null ? void 0 : _a.length);
        triggerValue = setTriggerValue(isCursorInEnd, oldCompositionValueRef.value, triggerValue, props.maxlength);
      }
      if (triggerValue !== mergedValue.value) {
        setValue(triggerValue);
        resolveOnChange(e.currentTarget, e, triggerChange, triggerValue);
      }
      emit("compositionend", e);
    };
    const instance = getCurrentInstance();
    watch(() => props.value, () => {
      var _a;
      if ("value" in instance.vnode.props || {})
        stateValue.value = (_a = props.value) != null ? _a : "";
    });
    const focus = (option) => {
      var _a;
      triggerFocus((_a = resizableTextArea.value) == null ? void 0 : _a.textArea, option);
    };
    const blur = () => {
      var _a, _b;
      (_b = (_a = resizableTextArea.value) == null ? void 0 : _a.textArea) == null ? void 0 : _b.blur();
    };
    const handleKeyDown = (e) => {
      if (e.keyCode === 13)
        emit("pressEnter", e);
      emit("keydown", e);
    };
    const onBlur = (e) => {
      var _a;
      (_a = props == null ? void 0 : props.onBlur) == null ? void 0 : _a.call(props, e);
      formItemContext.onFieldBlur();
    };
    const handleReset = (e) => {
      resolveOnChange(resizableTextArea.value.textArea, e, triggerChange);
      setValue("", () => {
        focus();
      });
    };
    const handleChange = (e) => {
      const {
        composing
      } = e.target;
      let triggerValue = e.target.value;
      compositing.value = !!(e.isComposing || composing);
      if (compositing.value && props.lazy || stateValue.value === triggerValue)
        return;
      if (hasMaxLength.value) {
        const target = e.target;
        const isCursorInEnd = target.selectionStart >= props.maxlength + 1 || target.selectionStart === triggerValue.length || !target.selectionStart;
        triggerValue = setTriggerValue(isCursorInEnd, mergedValue.value, triggerValue, props.maxlength);
      }
      resolveOnChange(e.currentTarget, e, triggerChange, triggerValue);
      setValue(triggerValue);
    };
    const renderTextArea = () => {
      var _a, _b;
      const {
        class: customClass
      } = attrs;
      const {
        bordered = true
      } = props;
      const resizeProps = {
        ...omit(props, ["allowClear"]),
        ...attrs,
        class: [{
          [`${prefixCls.value}-borderless`]: !bordered,
          [`${customClass}`]: customClass && !showCount.value,
          [`${prefixCls.value}-sm`]: size.value === "small",
          [`${prefixCls.value}-lg`]: size.value === "large"
        }, getStatusClassNames(prefixCls.value, mergedStatus.value), hashId.value],
        disabled: disabled.value,
        showCount: null,
        prefixCls: prefixCls.value,
        onInput: handleChange,
        onChange: handleChange,
        onBlur,
        onKeydown: handleKeyDown,
        onCompositionstart: onInternalCompositionStart,
        onCompositionend: onInternalCompositionEnd
      };
      if ((_a = props.valueModifiers) == null ? void 0 : _a.lazy)
        delete resizeProps.onInput;
      return createVNode(ResizableTextArea, {
        ...resizeProps,
        "id": (_b = resizeProps == null ? void 0 : resizeProps.id) != null ? _b : formItemContext.id.value,
        "ref": resizableTextArea,
        "maxlength": props.maxlength
      }, null);
    };
    expose({
      focus,
      blur,
      resizableTextArea
    });
    watchEffect(() => {
      let val = fixControlledValue(stateValue.value);
      if (!compositing.value && hasMaxLength.value && (props.value === null || props.value === void 0)) {
        val = fixEmojiLength(val, props.maxlength);
      }
      mergedValue.value = val;
    });
    return () => {
      var _a;
      const {
        maxlength,
        bordered = true,
        hidden
      } = props;
      const {
        style,
        class: customClass
      } = attrs;
      const inputProps = {
        ...props,
        ...attrs,
        prefixCls: prefixCls.value,
        inputType: "text",
        handleReset,
        direction: direction.value,
        bordered,
        style: showCount.value ? void 0 : style,
        hashId: hashId.value,
        disabled: (_a = props.disabled) != null ? _a : disabled.value
      };
      let textareaNode = createVNode(ClearableLabeledInput, {
        ...inputProps,
        "value": mergedValue.value,
        "status": props.status
      }, {
        element: renderTextArea
      });
      if (showCount.value || formItemInputContext.hasFeedback) {
        const valueLength = [...mergedValue.value].length;
        let dataCount = "";
        if (typeof showCount.value === "object") {
          dataCount = showCount.value.formatter({
            value: mergedValue.value,
            count: valueLength,
            maxlength
          });
        } else {
          dataCount = `${valueLength}${hasMaxLength.value ? ` / ${maxlength}` : ""}`;
        }
        textareaNode = createVNode("div", {
          "hidden": hidden,
          "class": classNames(`${prefixCls.value}-textarea`, {
            [`${prefixCls.value}-textarea-rtl`]: direction.value === "rtl",
            [`${prefixCls.value}-textarea-show-count`]: showCount.value,
            [`${prefixCls.value}-textarea-in-form-item`]: formItemInputContext.isFormItemInput
          }, `${prefixCls.value}-textarea-show-count`, customClass, hashId.value),
          "style": style,
          "data-count": typeof dataCount !== "object" ? dataCount : void 0
        }, [textareaNode, formItemInputContext.hasFeedback && createVNode("span", {
          "class": `${prefixCls.value}-textarea-suffix`
        }, [formItemInputContext.feedbackIcon])]);
      }
      return wrapSSR(textareaNode);
    };
  }
});

export { AInputTextArea as default };
//# sourceMappingURL=TextArea.mjs.map
