import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { InputMask } from "@react-input/mask";
import { Loader2 } from "lucide-react";
import { forwardRef, useId, useRef, useState, } from "react";
import { useForm } from "../../hooks/useForm";
import { IconRenderer } from "../../services/iconRenderer";
import { FieldError } from "../fieldError";
import { FieldLabel } from "../fieldLabel";
import { FieldWrapper } from "../fieldWrapper";
import "./style.css";
const BaseInput = forwardRef((props, ref) => {
    return _jsx("input", { ref: ref, ...props });
});
/**
 * MaskedInput component - used for text input fields with input masking support, labels, validation, icons, and loading states
 *
 * @param props - MaskedInput component properties
 * @param props.name - Required field name for form handling
 * @param props.mask - Input mask pattern (e.g., "___.___.___-__" for CPF)
 * @param props.replacement - Character or replacement configuration for mask positions
 * @param props.separate - Whether to separate mask characters from input value. Default: undefined
 * @param props.showMask - Whether to show the mask placeholder. Default: undefined
 * @param props.label - Optional label text to display above the input
 * @param props.errorMessage - Error message to display below the input
 * @param props.isLoading - Controls loading state with spinner. Default: false
 * @param props.size - Input size. Default: "md"
 * @param props.variant - Visual variant of the input. Default: "solid"
 * @param props.prefix - Text or icon to display at the beginning of the input
 * @param props.suffix - Text or icon to display at the end of the input
 * @param props.showAsterisk - Whether to show asterisk on label for required fields
 * @param props.leftIcon - Optional icon to display on the left side
 * @param props.rightIcon - Optional icon to display on the right side
 *
 * **...Other valid HTML properties for input element (except 'type' which is controlled by the mask)**
 *
 * @returns MaskedInput JSX element wrapped in FieldGroup with optional label and error
 *
 * @example
 * ```tsx
 * // Basic masked input for phone number
 * <MaskedInput
 *   name="phone"
 *   mask="(__) _____-____"
 *   replacement={{ _: /\d/ }}
 *   placeholder="(00) 00000-0000"
 * />
 *
 * // CPF input with label and validation
 * <MaskedInput
 *   name="cpf"
 *   label="CPF"
 *   mask="___.___.___-__"
 *   replacement="_"
 *   showAsterisk
 *   errorMessage="Please enter a valid CPF"
 *   showMask
 * />
 *
 * // Credit card input with icons and loading state
 * <MaskedInput
 *   name="creditCard"
 *   label="Credit Card"
 *   mask="____ ____ ____ ____"
 *   replacement={{ _: /\d/ }}
 *   leftIcon={CreditCardIcon}
 *   rightIcon={ShieldIcon}
 *   isLoading
 * />
 *
 * // Date input with prefix/suffix
 * <MaskedInput
 *   name="birthDate"
 *   label="Birth Date"
 *   mask="__/__/____"
 *   replacement="_"
 *   prefix="📅"
 *   variant="outline"
 *   separate
 * />
 *
 * // Large masked input with underline variant
 * <MaskedInput
 *   name="zipCode"
 *   label="ZIP Code"
 *   mask="_____-___"
 *   replacement={{ _: /\d/ }}
 *   size="lg"
 *   variant="underline"
 *   placeholder="00000-000"
 * />
 * ```
 */
function MaskedInput(props) {
    const { name, disabled, title, style, variant = "solid", separate, mask, showMask, replacement, label, className: wrapperClassName = "", prefix, suffix, isLoading = false, leftIcon, readOnly, onFocus, onBlur, errorMessage: baseErrorMessage, defaultValue, showAsterisk, rightIcon, size = "md", id, value, placeholder, ...rest } = props;
    const { fieldErrors } = useForm();
    const [isFocused, setIsFocused] = useState(false);
    const inputRef = useRef(null);
    const inputId = id || useId();
    const errorMessage = baseErrorMessage || fieldErrors?.[name];
    const isError = !!errorMessage;
    const isDisabled = disabled || isLoading;
    const iconSizes = { md: 20, lg: 20 };
    const iconSize = iconSizes[size];
    const loadingPosition = rightIcon ? "right" : "left";
    const showLeftSpinner = loadingPosition === "left" && isLoading;
    const showRightSpinner = loadingPosition === "right" && isLoading;
    function handleSectionClick() {
        if (isDisabled || !inputRef?.current)
            return;
        setIsFocused(true);
        inputRef.current.focus();
    }
    function handleFocus(e) {
        setIsFocused(true);
        if (onFocus)
            onFocus(e);
    }
    function handleBlur(e) {
        setIsFocused(false);
        if (onBlur)
            onBlur(e);
    }
    const hasPrefix = !!prefix ? "hasPrefix" : "";
    const hasSuffix = !!suffix ? "hasSuffix" : "";
    const errored = isError ? "errored" : "";
    const opacity = isDisabled || readOnly || isLoading ? "opacity" : "";
    const focused = isFocused ? "focused" : "";
    const className = `arkynMaskedInput ${hasPrefix} ${hasSuffix} ${variant} ${size} ${opacity} ${errored} ${focused}`;
    return (_jsxs(FieldWrapper, { className: wrapperClassName, children: [label && (_jsx(FieldLabel, { showAsterisk: showAsterisk, htmlFor: inputId, children: label })), _jsxs("section", { title: title, style: style, onClick: handleSectionClick, className: className, children: [_jsx(IconRenderer, { iconSize: iconSize, icon: prefix, className: "prefix" }), _jsx(IconRenderer, { show: showLeftSpinner, iconSize: iconSize, className: "spinner", icon: Loader2 }), _jsx(IconRenderer, { show: !isLoading, icon: leftIcon, iconSize: iconSize }), _jsx(InputMask, { component: BaseInput, mask: mask, replacement: replacement, separate: separate, showMask: showMask, ref: inputRef, onFocus: handleFocus, onBlur: handleBlur, disabled: isDisabled, readOnly: readOnly, id: inputId, name: name, defaultValue: defaultValue || undefined, placeholder: isDisabled ? value || placeholder : placeholder, value: isDisabled ? undefined : value, ...rest }), _jsx(IconRenderer, { show: !isLoading, icon: rightIcon, iconSize: iconSize }), _jsx(IconRenderer, { show: showRightSpinner, iconSize: iconSize, className: "spinner", icon: Loader2 }), _jsx(IconRenderer, { iconSize: iconSize, icon: suffix, className: "suffix" })] }), errorMessage && _jsx(FieldError, { children: errorMessage })] }));
}
export { MaskedInput };
