"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const useBindingState = require("../../form/hooks/useBindingState.cjs");
const arrays = require("../../utils/arrays.cjs");
const classNames = require("../../utils/classNames.cjs");
require("../../utils/globals.cjs");
require("zod");
const useForm = require("../../form/hooks/useForm.cjs");
const useDidUpdateEffect = require("../../hooks/useDidUpdateEffect.cjs");
const config_context = require("../config/config.context.cjs");
const input_component = require("../input/input.component.cjs");
const label_component = require("../label/label.component.cjs");
const statusWrapper_component = require("../statusWrapper/statusWrapper.component.cjs");
const validationErrors_component = require("../validationErrors/validationErrors.component.cjs");
const codeInput_utils = require("./codeInput.utils.cjs");
require("./codeInput.theme.css.cjs");
function _interopNamespaceDefault(e) {
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
  if (e) {
    for (const k in e) {
      if (k !== "default") {
        const d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: () => e[k]
        });
      }
    }
  }
  n.default = e;
  return Object.freeze(n);
}
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
const CodeInputPart = React__namespace.forwardRef(
  ({ bind, part, ...inputProps }, ref) => {
    const length = React__namespace.useMemo(() => codeInput_utils.getLengthFromPart(part), [part]);
    if (typeof part === "string") {
      return jsxRuntime.jsx("p", { className: "arm-code-input-part-text", children: part });
    }
    if (typeof part === "number") {
      return jsxRuntime.jsx(input_component.Input, { ref, bind, ...inputProps, className: "arm-code-input-part-input", style: { "--arm-code-input-length": length }, "data-length": length, onClick: (event) => event.currentTarget.select(), maxLength: part });
    }
    const { className, ...textInputProps } = part;
    return jsxRuntime.jsx(input_component.Input, { ref, bind, className: classNames.concat("arm-code-input-part-input", className), style: {
      ...textInputProps.style || {},
      "--arm-code-input-length": length
    }, "data-length": length, onClick: (event) => event.currentTarget.select(), ...inputProps, ...textInputProps, maxLength: part.length, displaySize: part.displaySize });
  }
  // type assertion to ensure generic works with RefForwarded component
  // DO NOT CHANGE TYPE WITHOUT CHANGING THIS, FIND TYPE BY INSPECTING React.forwardRef
);
CodeInputPart.displayName = "CodeInputPart";
const CodeInput = React__namespace.forwardRef(
  ({ className, parts, bind, onChange, validationMode, validationErrorMessages, errorIcon, error, value, pending, statusPosition, leftOverlay, rightOverlay, scrollValidationErrorsIntoView, displaySize, label, required, requiredIndicator, hideIconOnStatus, statusClassName, validationErrorsClassName, labelClassName, labelId, disableOnPending, disabled, autoValidate, ...nativeProps }, ref) => {
    var _a;
    const inputRefs = React__namespace.useRef([]);
    const [boundValue, setBoundValue, bindConfig] = useBindingState.useBindingState(bind, {
      onChange,
      validationErrorMessages,
      validationMode,
      value,
      autoValidate
    });
    const globals = config_context.useArmstrongConfig({
      validationMode: bindConfig.validationMode,
      inputStatusPosition: statusPosition,
      inputDisplaySize: displaySize,
      requiredIndicator,
      hideInputErrorIconOnStatus: hideIconOnStatus,
      disableControlOnPending: disableOnPending,
      scrollValidationErrorsIntoView,
      validationErrorIcon: errorIcon,
      autoValidate: bindConfig.autoValidate
    });
    const goNextPart = React__namespace.useCallback((partIndex) => {
      var _a2;
      const nextIndex = parts.slice(partIndex + 1).findIndex((part) => typeof part !== "string") + partIndex + 1;
      if (nextIndex !== -1) {
        (_a2 = inputRefs.current[nextIndex]) == null ? void 0 : _a2.focus();
      }
    }, [parts]);
    const goPreviousPart = React__namespace.useCallback((partIndex) => {
      var _a2;
      const previousIndex = arrays.findLastIndex(parts.slice(0, partIndex), (part) => typeof part !== "string");
      if (previousIndex !== -1) {
        (_a2 = inputRefs.current[previousIndex]) == null ? void 0 : _a2.focus();
      }
    }, [parts]);
    const getValueForPart = React__namespace.useCallback((partIndex, incomingValue) => {
      const sliceStart = parts.slice(0, partIndex).reduce((output, part) => output + codeInput_utils.getLengthFromPart(part), 0);
      const sliceEnd = sliceStart + codeInput_utils.getLengthFromPart(parts[partIndex]);
      return (incomingValue == null ? void 0 : incomingValue.slice(sliceStart, sliceEnd)) || "";
    }, [parts]);
    const onPartValueChange = React__namespace.useCallback((event, partIndex) => {
      const currentPartLength = codeInput_utils.getLengthFromPart(parts[partIndex]);
      const currentPartValue = event.currentTarget.value || "";
      if (currentPartValue.length >= currentPartLength) {
        goNextPart(partIndex);
      }
    }, [parts, goNextPart]);
    const onPaste = React__namespace.useCallback((event) => {
      event.preventDefault();
      const pasteValue = event.clipboardData.getData("text/plain");
      const target = event.target;
      const partIndex = inputRefs.current.indexOf(target);
      const selectionStart = Math.min(target.selectionStart ?? 0, target.selectionEnd ?? 0);
      const selectionEnd = Math.max(target.selectionStart ?? 0, target.selectionEnd ?? 0);
      const insertionStart = new Array(partIndex).fill(null).reduce((memo, _, i) => {
        const part = parts[i];
        return memo + codeInput_utils.getLengthFromPart(part);
      }, 0) + selectionStart;
      const insertionEnd = insertionStart + (selectionEnd - selectionStart);
      const startSlice = (boundValue == null ? void 0 : boundValue.slice(0, insertionStart)) ?? "";
      const endSlice = (boundValue == null ? void 0 : boundValue.slice(insertionEnd)) ?? "";
      const newValue = startSlice + pasteValue + endSlice;
      setBoundValue(newValue);
    }, [setBoundValue, boundValue, parts]);
    const boundValueArray = React__namespace.useMemo(() => {
      return parts.map((_, partIndex) => getValueForPart(partIndex, boundValue));
    }, [getValueForPart, parts, boundValue]);
    const onKeyDown = React__namespace.useCallback((event, partIndex, part) => {
      var _a2;
      switch (event.key) {
        case "Backspace": {
          if (((_a2 = event.currentTarget.value) == null ? void 0 : _a2.length) <= 0 && partIndex > 0) {
            goPreviousPart(partIndex);
          }
          break;
        }
        case "ArrowLeft": {
          if (event.currentTarget.selectionStart === 0 && partIndex > 0) {
            goPreviousPart(partIndex);
          }
          break;
        }
        case "ArrowRight": {
          if (event.currentTarget.selectionEnd === codeInput_utils.getLengthFromPart(part) && partIndex < parts.length) {
            goNextPart(partIndex);
          }
          break;
        }
      }
    }, [goPreviousPart, goNextPart, parts]);
    const { formProp, formState } = useForm.useForm({
      parts: boundValueArray
    });
    React__namespace.useEffect(() => {
      var _a2;
      setBoundValue == null ? void 0 : setBoundValue((_a2 = formState == null ? void 0 : formState.parts) == null ? void 0 : _a2.join(""));
    }, [formState]);
    useDidUpdateEffect.useDidUpdateEffect(() => {
      if (globals.autoValidate && bindConfig.isTouched) {
        bindConfig.validate();
      }
    }, [boundValue]);
    const onBlur = React__namespace.useCallback(() => {
      if ((formState == null ? void 0 : formState.parts.every((p) => p)) && globals.autoValidate && !bindConfig.isTouched) {
        bindConfig.validate();
        bindConfig.setTouched(true);
      }
    }, [bindConfig, formState == null ? void 0 : formState.parts, globals.autoValidate]);
    const showLeftOverlay = leftOverlay && (globals.inputStatusPosition !== "left" || !globals.hideInputErrorIconOnStatus || !pending && !bindConfig.shouldShowValidationErrorIcon);
    const showRightOverlay = rightOverlay && (globals.inputStatusPosition !== "right" || !globals.hideInputErrorIconOnStatus || !pending && !bindConfig.shouldShowValidationErrorIcon);
    return jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { ref, title: "Code input", ...nativeProps, children: [label && jsxRuntime.jsx(label_component.Label, { className: classNames.concat("arm-code-input-label", labelClassName), id: labelId, required, requiredIndicator: globals.requiredIndicator, displaySize: globals.inputDisplaySize, children: label }), jsxRuntime.jsx("div", { className: classNames.concat("arm-code-input", className), children: jsxRuntime.jsx(statusWrapper_component.StatusWrapper, { error: error || !!bindConfig.validationErrorMessages.length, errorIcon: bindConfig.validationErrorIcon, statusPosition: globals.inputStatusPosition, pending, validationMode: bindConfig.validationMode, className: statusClassName, children: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showLeftOverlay && leftOverlay, parts == null ? void 0 : parts.map((part, index) => jsxRuntime.jsx(CodeInputPart, { type: "text", bind: formProp("parts", index).bind(), part, onChange: (event) => onPartValueChange(event, index), onKeyDown: (event) => onKeyDown(event, index, +part), onPaste, onBlur, disabled: disabled || pending && globals.disableControlOnPending, ref: (r) => {
      inputRefs.current[index] = r;
    }, displaySize: globals.inputDisplaySize }, index)), showRightOverlay && rightOverlay] }) }) })] }), !!((_a = bindConfig.validationErrorMessages) == null ? void 0 : _a.length) && bindConfig.shouldShowValidationErrorMessage && jsxRuntime.jsx(validationErrors_component.ValidationErrors, { className: validationErrorsClassName, validationErrors: bindConfig.validationErrorMessages, scrollIntoView: globals.scrollValidationErrorsIntoView })] });
  }
  // type assertion to ensure generic works with RefForwarded component
  // DO NOT CHANGE TYPE WITHOUT CHANGING THIS, FIND TYPE BY INSPECTING React.forwardRef
);
CodeInput.displayName = "Code Input";
exports.CodeInput = CodeInput;
//# sourceMappingURL=codeInput.component.cjs.map
