import { useCallback, useRef, useState } from 'react';
import {
    InputGroup,
    InputGroupAddon,
    InputGroupInput,
    InputGroupText,
} from '@/components/ui/input-group';

type NumberInputProps = {
    id?: string;
    name?: string;
    defaultValue?: number;
    value?: number;
    onValueChange?: (value: number) => void;
    placeholder?: string;
    disabled?: boolean;
    min?: number;
    max?: number;
    suffix?: string;
    className?: string;
};

function formatDisplay(value: number): string {
    return value.toLocaleString('id-ID');
}

function parseText(value: string): number {
    const cleaned = value.replace(/[^0-9]/g, '');

    return cleaned === '' ? 0 : parseInt(cleaned, 10);
}

export function NumberInput({
    id,
    name,
    defaultValue = 0,
    value,
    onValueChange,
    placeholder = '0',
    disabled = false,
    min,
    max,
    suffix,
    className,
}: NumberInputProps) {
    const isControlled = value !== undefined;
    const [displayValue, setDisplayValue] = useState(
        formatDisplay(isControlled ? value : defaultValue),
    );
    const lastValidRef = useRef(isControlled ? value : defaultValue);
    const [prevValue, setPrevValue] = useState(value);

    if (isControlled && value !== prevValue) {
        setPrevValue(value);
        setDisplayValue(formatDisplay(value));
    }

    const handleChange = useCallback(
        (e: React.ChangeEvent<HTMLInputElement>) => {
            const raw = parseText(e.target.value);
            let clamped = raw;

            if (min !== undefined && raw < min) {
                clamped = min;
            }

            if (max !== undefined && raw > max) {
                clamped = max;
            }

            lastValidRef.current = clamped;
            setDisplayValue(formatDisplay(clamped));
            onValueChange?.(clamped);
        },
        [min, max, onValueChange],
    );

    const handleBlur = useCallback(() => {
        setDisplayValue(formatDisplay(lastValidRef.current));
    }, []);

    return (
        <InputGroup className={className}>
            <InputGroupInput
                id={id}
                name={name}
                type="text"
                inputMode="numeric"
                value={displayValue}
                onChange={handleChange}
                onBlur={handleBlur}
                placeholder={placeholder}
                disabled={disabled}
                autoComplete="off"
            />
            {suffix && (
                <InputGroupAddon align="inline-end">
                    <InputGroupText>{suffix}</InputGroupText>
                </InputGroupAddon>
            )}
        </InputGroup>
    );
}
