import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import React__default, { useRef, useState, useEffect, useCallback } from 'react';
import { cn } from '../../../utils/cn.js';
import { Input } from '../Input/Input.js';
import '../Input/Input.theme.js';
import { FormLabel } from '../FormLabel/FormLabel.js';
import { inputOTPTheme } from './InputOTP.theme.js';

/**
 * InputOTP component for entering one-time passwords or verification codes.
 *
 * @component
 * @example
 * ```tsx
 * <InputOTP
 *   length={6}
 *   value={otpValue}
 *   onChange={setOtpValue}
 *   onComplete={handleOtpComplete}
 *   label="Enter verification code"
 * />
 * ```
 */
const InputOTP = React__default.forwardRef(({ length = 6, value = '', onChange, onComplete, disabled = false, label, helperText, error, autoFocus = true, className, ...props }, ref) => {
    const inputRefs = useRef([]);
    const theme = inputOTPTheme;
    // Internal state for uncontrolled usage
    const [internalValue, setInternalValue] = useState('');
    // Use controlled value if provided, otherwise use internal state
    const currentValue = value !== undefined ? value : internalValue;
    const setValue = onChange || setInternalValue;
    // Convert value to array of characters
    const valueArray = currentValue.padEnd(length, '').split('').slice(0, length);
    // Auto-focus first input on mount
    useEffect(() => {
        if (autoFocus && inputRefs.current[0] && !disabled) {
            inputRefs.current[0].focus();
        }
    }, [autoFocus, disabled]);
    // Handle input change
    const handleChange = useCallback((index, newValue) => {
        var _a;
        if (disabled)
            return;
        // Only allow single character (take last character if multiple)
        const char = newValue.slice(-1);
        // Create new value array
        const newValueArray = [...valueArray];
        newValueArray[index] = char;
        // Convert back to string and remove trailing spaces
        const newValueString = newValueArray.join('').trimEnd();
        setValue(newValueString);
        // Auto-focus next input if character was entered
        if (char && index < length - 1) {
            (_a = inputRefs.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus();
        }
        // Check if OTP is complete
        if (newValueString.length === length) {
            onComplete === null || onComplete === void 0 ? void 0 : onComplete(newValueString);
        }
    }, [disabled, valueArray, length, setValue, onComplete]);
    // Handle key down for navigation and deletion
    const handleKeyDown = useCallback((index, event) => {
        var _a, _b, _c, _d, _e;
        if (disabled)
            return;
        switch (event.key) {
            case 'Backspace':
                if (!valueArray[index] && index > 0) {
                    // If current field is empty, move to previous and clear it
                    event.preventDefault();
                    (_a = inputRefs.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
                    handleChange(index - 1, '');
                }
                break;
            case 'Delete':
                // Clear current field
                event.preventDefault();
                handleChange(index, '');
                break;
            case 'ArrowLeft':
                event.preventDefault();
                if (index > 0) {
                    (_b = inputRefs.current[index - 1]) === null || _b === void 0 ? void 0 : _b.focus();
                }
                break;
            case 'ArrowRight':
                event.preventDefault();
                if (index < length - 1) {
                    (_c = inputRefs.current[index + 1]) === null || _c === void 0 ? void 0 : _c.focus();
                }
                break;
            case 'Home':
                event.preventDefault();
                (_d = inputRefs.current[0]) === null || _d === void 0 ? void 0 : _d.focus();
                break;
            case 'End':
                event.preventDefault();
                (_e = inputRefs.current[length - 1]) === null || _e === void 0 ? void 0 : _e.focus();
                break;
        }
    }, [disabled, valueArray, length, handleChange]);
    // Handle paste
    const handlePaste = useCallback((event) => {
        var _a;
        if (disabled)
            return;
        event.preventDefault();
        const pastedData = event.clipboardData.getData('text').slice(0, length);
        if (pastedData) {
            setValue(pastedData);
            // Focus the next empty field or last field
            const nextIndex = Math.min(pastedData.length, length - 1);
            (_a = inputRefs.current[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus();
            // Check if OTP is complete
            if (pastedData.length === length) {
                onComplete === null || onComplete === void 0 ? void 0 : onComplete(pastedData);
            }
        }
    }, [disabled, length, setValue, onComplete]);
    // Handle focus and blur (simplified since we removed focus state)
    const handleFocus = useCallback((index) => {
        // Focus logic can be added here if needed
    }, []);
    const handleBlur = useCallback(() => {
        // Blur logic can be added here if needed
    }, []);
    // State class for CSS selectors (matches Input component pattern)
    const stateClass = error
        ? "state-invalid"
        : disabled
            ? "state-disabled"
            : "state-default";
    // Build classes with shadcn pattern - user className has highest priority
    const wrapperClasses = cn(theme.wrapperStyle, stateClass, className);
    const containerClasses = cn(theme.containerStyle);
    // Get input classes based on position within group
    const getInputClasses = (index) => {
        if (length === 6) {
            // For 6-digit: two groups of 3
            const isFirst = index === 0 || index === 3;
            const isLast = index === 2 || index === 5;
            return cn(theme.inputGroupStyle, 'relative focus-within:z-10', {
                'rounded-r-none -mr-px': !isLast,
                'rounded-l-none': !isFirst,
            });
        }
        else {
            // For other lengths: one group
            const isFirst = index === 0;
            const isLast = index === length - 1;
            return cn(theme.inputGroupStyle, 'relative focus-within:z-10', {
                'rounded-r-none -mr-px': !isLast,
                'rounded-l-none': !isFirst,
            });
        }
    };
    return (jsxs("div", { ref: ref, className: wrapperClasses, ...props, children: [label && (jsx(FormLabel, { htmlFor: `otp-input-0`, state: error ? "invalid" : disabled ? "disabled" : "default", children: label })), jsx("div", { className: containerClasses, children: length === 6 ? (
                // For 6-digit OTP, create two groups of 3
                jsxs(Fragment, { children: [jsx("div", { className: "flex", children: Array.from({ length: 3 }, (_, i) => (jsx(Input, { ref: (el) => {
                                    inputRefs.current[i] = el;
                                }, id: `otp-input-${i}`, type: "text", value: valueArray[i] || '', onChange: (e) => handleChange(i, e.target.value), onKeyDown: (e) => handleKeyDown(i, e), onFocus: () => handleFocus(i), onBlur: handleBlur, onPaste: i === 0 ? handlePaste : undefined, disabled: disabled, maxLength: 1, className: theme.inputStyle, inputGroupClassName: getInputClasses(i), wrapperClassName: "space-y-0 w-auto" }, i))) }), jsx("span", { className: theme.separatorStyle, children: "\u2014" }), jsx("div", { className: "flex", children: Array.from({ length: 3 }, (_, i) => {
                                const index = i + 3;
                                return (jsx(Input, { ref: (el) => {
                                        inputRefs.current[index] = el;
                                    }, id: `otp-input-${index}`, type: "text", value: valueArray[index] || '', onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), onFocus: () => handleFocus(index), onBlur: handleBlur, disabled: disabled, maxLength: 1, className: theme.inputStyle, inputGroupClassName: getInputClasses(index), wrapperClassName: "space-y-0 w-auto" }, index));
                            }) })] })) : (
                // For other lengths, create one group
                jsx("div", { className: "flex", children: Array.from({ length }, (_, index) => (jsx(Input, { ref: (el) => {
                            inputRefs.current[index] = el;
                        }, id: `otp-input-${index}`, type: "text", value: valueArray[index] || '', onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), onFocus: () => handleFocus(index), onBlur: handleBlur, onPaste: index === 0 ? handlePaste : undefined, disabled: disabled, maxLength: 1, className: theme.inputStyle, inputGroupClassName: getInputClasses(index), wrapperClassName: "space-y-0 w-auto" }, index))) })) }), (error || helperText) && (jsx("div", { className: cn(theme.helperText), children: error || helperText }))] }));
});
InputOTP.displayName = 'InputOTP';

export { InputOTP };
