import { useState, useRef, useEffect, useMemo, useCallback } from "react";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const useCallbackRef = (callback) => {
    const callbackRef = useRef(callback);
    useEffect(() => {
        callbackRef.current = callback;
    });
    // https://github.com/facebook/react/issues/19240
    return useMemo(() => ((...args) => { var _a; return (_a = callbackRef.current) === null || _a === void 0 ? void 0 : _a.call(callbackRef, ...args); }), []);
};
const useUncontrolledState = ({ defaultValue, onChange, }) => {
    const uncontrolledState = useState(defaultValue);
    const [value] = uncontrolledState;
    const prevValueRef = useRef(value);
    const handleChange = useCallbackRef(onChange === null || onChange === void 0 ? void 0 : onChange.func);
    useEffect(() => {
        if (prevValueRef.current !== value && onChange) {
            handleChange({ type: onChange.key, data: value });
            prevValueRef.current = value;
        }
    }, [value, prevValueRef, handleChange]);
    return uncontrolledState;
};
const useControllableState = ({ controlledValue, onChange, defaultValue, }) => {
    const [uncontrolledValue, setUncontrolledValue] = useUncontrolledState({
        defaultValue,
        onChange,
    });
    const isControlled = controlledValue !== undefined;
    const value = isControlled ? controlledValue : uncontrolledValue;
    const handleChange = useCallbackRef(onChange === null || onChange === void 0 ? void 0 : onChange.func);
    const setValue = useCallback((nextValue) => {
        if (isControlled) {
            const setter = nextValue;
            const v = typeof nextValue === "function" ? setter(controlledValue) : nextValue;
            if (v !== controlledValue && onChange)
                handleChange({ type: onChange.key, data: v });
        }
        else {
            setUncontrolledValue(nextValue);
        }
    }, [isControlled, value, setUncontrolledValue, handleChange]);
    return [value, setValue];
};
export default useControllableState;
//# sourceMappingURL=useControllableState.js.map