import { useEffect, useRef } from "react";

type Awaited<T> = T extends PromiseLike<infer U> ? U : T;

const useFirstResolvedPromise = <T extends Promise<any>>(promise: T): Promise<Awaited<T>> => {
    const hasResolvedRef = useRef(false);
    const currentPromiseRef = useRef<T | null>(null);

    const resultPromiseRef = useRef<Promise<Awaited<T>>>(
        new Promise((resolve) => {
            // Placeholder promise to ensure the returned promise is consistent
            // This will be replaced with the first resolved promise
        }),
    );

    useEffect(() => {
        if (hasResolvedRef.current) {
            return () => {
                // Silence is golden.
            };
        }

        currentPromiseRef.current = promise;

        promise
            .then((res: Awaited<T>) => {
                if (currentPromiseRef.current === promise && !hasResolvedRef.current) {
                    hasResolvedRef.current = true;
                    resultPromiseRef.current = Promise.resolve(res);
                }
            })
            .catch(() => {
                // Handle promise rejection if needed
            });

        return () => {
            // Clean up if the component unmounts or the promise changes
            currentPromiseRef.current = null;
        };
    }, [promise]);

    return resultPromiseRef.current;
};

export { useFirstResolvedPromise };
