import { jsx } from 'react/jsx-runtime';
import React__default, { useState, useRef, useEffect, useCallback } from 'react';
import { Input } from '../Input/Input.js';
import '../Input/Input.theme.js';
import { formatDateInput, isValidDateInput } from '../Input/inputMasks.js';
import { cn } from '../../../utils/cn.js';

/**
 * InputDate component for entering dates with automatic masking
 *
 * Features:
 * - Single input field with automatic slash insertion (e.g., "12252024" → "12/25/2024")
 * - Multiple format support (MM/DD/YYYY, DD/MM/YYYY, YYYY/MM/DD)
 * - Date validation (valid month, day, year ranges)
 * - Min/max date range validation
 * - Cursor position handling
 * - Paste support
 * - Inherits all Input component features (icons, addons, sizes, states, theming)
 *
 * @component
 * @example
 * ```tsx
 * <InputDate
 *   label="Date of Birth"
 *   value={date}
 *   onChange={setDate}
 *   dateFormat="MM/DD/YYYY"
 *   maxDate={new Date()}
 *   onComplete={(date) => console.log('Valid date entered:', date)}
 * />
 * ```
 */
const InputDate = React__default.forwardRef(({ value = '', onChange, onComplete, dateFormat, minDate, maxDate, className, ...props }, ref) => {
    const [maskedValue, setMaskedValue] = useState('');
    const inputRef = useRef(null);
    const cursorPositionRef = useRef(null);
    const getDefaultDateFormat = () => {
        if (typeof navigator !== 'undefined') {
            const lang = (navigator.language || '').toLowerCase();
            if (lang.startsWith('en-us'))
                return 'MM/DD/YYYY';
        }
        return 'DD/MM/YYYY';
    };
    const resolvedFormat = dateFormat !== null && dateFormat !== void 0 ? dateFormat : getDefaultDateFormat();
    // Initialize masked value from prop value
    useEffect(() => {
        if (value) {
            const formatted = formatDateInput(value, resolvedFormat);
            setMaskedValue(formatted);
        }
        else {
            setMaskedValue('');
        }
    }, [value, resolvedFormat]);
    // Generate placeholder based on format
    const getPlaceholder = () => {
        return resolvedFormat.toLowerCase().replace(/m/g, 'm').replace(/d/g, 'd').replace(/y/g, 'y');
    };
    // Handle backspace to delete slash along with digit
    const handleKeyDown = useCallback((e) => {
        if (e.key === 'Backspace' && !e.metaKey && !e.ctrlKey) {
            const cursorPos = e.currentTarget.selectionStart;
            const cursorEnd = e.currentTarget.selectionEnd;
            // Only handle if no text is selected and cursor is right after a slash
            if (cursorPos === cursorEnd && cursorPos !== null && cursorPos > 0) {
                const currentValue = e.currentTarget.value;
                const charBeforeCursor = currentValue[cursorPos - 1];
                // If the character before cursor is a slash, delete it along with the digit before it
                if (charBeforeCursor === '/') {
                    e.preventDefault();
                    const newValue = currentValue.slice(0, cursorPos - 2) + currentValue.slice(cursorPos);
                    const masked = formatDateInput(newValue, resolvedFormat);
                    setMaskedValue(masked);
                    onChange === null || onChange === void 0 ? void 0 : onChange(masked);
                    // Set cursor position after the deletion
                    setTimeout(() => {
                        if (inputRef.current) {
                            const newPos = Math.max(0, cursorPos - 2);
                            inputRef.current.setSelectionRange(newPos, newPos);
                        }
                    }, 0);
                }
            }
        }
    }, [resolvedFormat, onChange]);
    // Handle input change with masking
    const handleChange = useCallback((e) => {
        const originalValue = e.target.value;
        cursorPositionRef.current = e.target.selectionStart;
        // Apply date masking
        const masked = formatDateInput(originalValue, resolvedFormat);
        setMaskedValue(masked);
        // Call onChange with formatted value
        onChange === null || onChange === void 0 ? void 0 : onChange(masked);
        // Check if date is complete and valid
        if (masked.length === 10) {
            if (isValidDateInput(masked, resolvedFormat)) {
                // Parse the date based on format
                const parts = masked.split('/');
                let month, day, year;
                switch (resolvedFormat) {
                    case 'MM/DD/YYYY':
                        month = parseInt(parts[0], 10);
                        day = parseInt(parts[1], 10);
                        year = parseInt(parts[2], 10);
                        break;
                    case 'DD/MM/YYYY':
                        day = parseInt(parts[0], 10);
                        month = parseInt(parts[1], 10);
                        year = parseInt(parts[2], 10);
                        break;
                    case 'YYYY/MM/DD':
                        year = parseInt(parts[0], 10);
                        month = parseInt(parts[1], 10);
                        day = parseInt(parts[2], 10);
                        break;
                    default:
                        return;
                }
                const dateObj = new Date(year, month - 1, day);
                // Check min/max date constraints
                let isInRange = true;
                if (minDate && dateObj < minDate)
                    isInRange = false;
                if (maxDate && dateObj > maxDate)
                    isInRange = false;
                if (isInRange) {
                    onComplete === null || onComplete === void 0 ? void 0 : onComplete(dateObj);
                }
            }
        }
        // Adjust cursor position - move to end after formatting
        setTimeout(() => {
            if (inputRef.current) {
                // Always place cursor at the end of the formatted value
                const newPosition = masked.length;
                inputRef.current.setSelectionRange(newPosition, newPosition);
            }
        }, 0);
    }, [resolvedFormat, onChange, onComplete, minDate, maxDate]);
    // Set the ref from forwardRef
    const setInputRef = (el) => {
        inputRef.current = el;
        if (typeof ref === 'function') {
            ref(el);
        }
        else if (ref) {
            ref.current = el;
        }
    };
    return (jsx(Input, { ref: setInputRef, type: "text", inputMode: "numeric", value: maskedValue, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: props.placeholder || getPlaceholder(), maxLength: 10, className: cn("tabular-nums", className), ...props }));
});
InputDate.displayName = 'InputDate';

export { InputDate };
