import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { useBindingState } from "../../form/hooks/useBindingState.js";
import { useSSRLayoutEffect } from "../../hooks/useSSRLayoutEffect.js";
import { concat } from "../../utils/classNames.js";
import "../../utils/globals.js";
import "zod";
import { useDebounce } from "../../hooks/useDebounce.js";
import { useDidUpdateEffect } from "../../hooks/useDidUpdateEffect.js";
import { onBlurWorkaround } from "../../workarounds/radixDialog.js";
import { useArmstrongConfig } from "../config/config.context.js";
import { InputWrapper } from "../inputWrapper/inputWrapper.component.js";
import "./input.theme.css.js";
const DebounceInputBase = React.forwardRef(({ milliseconds, value, onValueChange, onChange, ...nativeProps }, ref) => {
  const [actualValue, setActualValue] = useDebounce(milliseconds, value, onValueChange);
  const onChangeEvent = React.useCallback((e) => {
    setActualValue(e.currentTarget.value);
    onChange == null ? void 0 : onChange(e);
  }, [setActualValue, onChange]);
  return jsx("input", { ref, value: actualValue, onChange: onChangeEvent, ...nativeProps });
});
DebounceInputBase.displayName = "DebounceInput";
const Input = React.forwardRef(
  ({ bind, onChange, value, className, leftOverlay, rightOverlay, validationErrorMessages, validationMode, errorIcon: validationErrorIcon, pending, disabled, disableOnPending, statusPosition, hideIconOnStatus, onValueChange, scrollValidationErrorsIntoView, delay, validationErrorsClassName, statusClassName, inputClassName, label, required, requiredIndicator, displaySize, labelClassName, labelId, wrapperTestId, error, autoValidate, ...nativeProps }, ref) => {
    const reactId = React.useId();
    const id = nativeProps.id ?? reactId;
    const [boundValue, setBoundValue, bindConfig] = useBindingState(bind, {
      value: value == null ? void 0 : value.toString(),
      validationErrorMessages,
      validationMode,
      validationErrorIcon,
      autoValidate
    });
    const [internalValue, setInternalValue] = React.useState(boundValue == null ? void 0 : boundValue.toString());
    useSSRLayoutEffect(() => {
      if ((boundValue == null ? void 0 : boundValue.toString()) !== (internalValue == null ? void 0 : internalValue.toString())) {
        setInternalValue(boundValue == null ? void 0 : boundValue.toString());
      }
    }, [boundValue]);
    const globals = useArmstrongConfig({
      validationMode: bindConfig.validationMode,
      disableControlOnPending: disableOnPending,
      hideInputErrorIconOnStatus: hideIconOnStatus,
      inputDisplaySize: displaySize,
      inputStatusPosition: statusPosition,
      requiredIndicator,
      validationErrorIcon: bindConfig.validationErrorIcon,
      scrollValidationErrorsIntoView,
      autoValidate: bindConfig.autoValidate
    });
    const parseValue = React.useCallback((unparsedValue) => {
      if (nativeProps.type !== "number") {
        return unparsedValue;
      }
      if (!unparsedValue) {
        return void 0;
      }
      if (!Number.isNaN(parseFloat(unparsedValue))) {
        return parseFloat(unparsedValue);
      }
      return null;
    }, [nativeProps.type]);
    const onBindValueChange = React.useCallback((parsedValue) => {
      var _a, _b, _c;
      const formattedValue = ((_c = (_b = (_a = bind == null ? void 0 : bind.bindConfig) == null ? void 0 : _a.format) == null ? void 0 : _b.toData) == null ? void 0 : _c.call(_b, parsedValue)) || parsedValue;
      setBoundValue(formattedValue);
    }, [setBoundValue, bind]);
    const updateValue = React.useCallback((newValue) => {
      const parsedValue = parseValue(newValue);
      if (parsedValue !== null) {
        onBindValueChange(parsedValue);
        onValueChange == null ? void 0 : onValueChange(parsedValue);
      }
    }, [parseValue, onBindValueChange, onValueChange]);
    const onValueChangeEvent = React.useCallback((currentValue) => {
      setInternalValue(currentValue);
      updateValue(currentValue);
    }, [updateValue]);
    const onValueChangeRaw = React.useCallback((event) => {
      onChange == null ? void 0 : onChange(event);
      const newValue = event.currentTarget.value;
      setInternalValue(newValue);
      updateValue(newValue);
    }, [onChange, updateValue]);
    useDidUpdateEffect(() => {
      if (globals.autoValidate && bindConfig.isTouched) {
        bindConfig.validate();
      }
    }, [boundValue]);
    const onBlurEvent = React.useCallback((event) => {
      var _a;
      if (globals.autoValidate && !bindConfig.isTouched) {
        bindConfig.validate();
      }
      bindConfig.setTouched(true);
      onBlurWorkaround(event);
      return (_a = nativeProps.onBlur) == null ? void 0 : _a.call(nativeProps, event);
    }, [bindConfig, globals.autoValidate, nativeProps]);
    const inputProps = {
      id,
      className: concat("arm-input-base-input", inputClassName),
      /** fallback to an empty string if bind is passed in but bound value is undefined to avoid React warning */
      value: (internalValue == null ? void 0 : internalValue.toString()) ?? (bind && ""),
      disabled,
      ...nativeProps,
      onBlur: onBlurEvent
    };
    return jsxs(InputWrapper, { "data-size": globals.inputDisplaySize, className: concat(className, "arm-input-base"), statusClassName: concat(statusClassName, "arm-input-base-status"), validationErrorsClassName: concat(validationErrorsClassName, "arm-input-base-validation"), leftOverlay, rightOverlay, validationErrorMessages: bindConfig.validationErrorMessages, errorIcon: bindConfig.validationErrorIcon, validationMode: bindConfig.validationMode, pending, disabled, statusPosition: globals.inputStatusPosition, scrollValidationErrorsIntoView: globals.scrollValidationErrorsIntoView, disableOnPending: globals.disableControlOnPending, hideIconOnStatus: globals.hideInputErrorIconOnStatus, label, labelId: labelId ?? id, labelClassName: concat(labelClassName, "arm-input-base-label"), required, error, requiredIndicator: globals.requiredIndicator, "data-testid": wrapperTestId, displaySize: globals.inputDisplaySize, children: [!!delay && jsx(DebounceInputBase, { ...nativeProps, ...inputProps, milliseconds: delay, onChange, onValueChange: onValueChangeEvent, ref, "data-size": displaySize }), !delay && jsx("input", { ...nativeProps, ...inputProps, onChange: onValueChangeRaw, ref, "data-size": displaySize })] });
  }
  // type assertion to ensure generic works with RefForwarded component
  // DO NOT CHANGE TYPE WITHOUT CHANGING THIS, FIND TYPE BY INSPECTING React.forwardRef
);
Input.displayName = "Input";
export {
  Input
};
//# sourceMappingURL=input.component.js.map
