import { useMemo, useRef, useState } from 'react';
import { useSyncedRef } from '../useSyncedRef/index.js';
export function useAsync(asyncFn, initialValue) {
    const [state, setState] = useState({
        status: 'not-executed',
        error: undefined,
        result: initialValue,
    });
    const promiseRef = useRef();
    const argsRef = useRef();
    const methods = useSyncedRef({
        execute(...params) {
            argsRef.current = params;
            const promise = asyncFn(...params);
            promiseRef.current = promise;
            setState((s) => ({ ...s, status: 'loading' }));
            promise.then((result) => {
                if (promise === promiseRef.current) {
                    setState((s) => ({ ...s, status: 'success', error: undefined, result }));
                }
            }, (error) => {
                if (promise === promiseRef.current) {
                    setState((s) => ({ ...s, status: 'error', error }));
                }
            });
            return promise;
        },
        reset() {
            setState({
                status: 'not-executed',
                error: undefined,
                result: initialValue,
            });
            promiseRef.current = undefined;
            argsRef.current = undefined;
        },
    });
    return [
        state,
        useMemo(() => ({
            reset() {
                methods.current.reset();
            },
            execute: (...params) => methods.current.execute(...params),
        }), []),
        { promise: promiseRef.current, lastArgs: argsRef.current },
    ];
}
