import { Fragment, useMemo } from "react";

import { yieldLazyLoad } from "../utils/yieldLazyLoad.js";

import type { FC, PropsWithChildren } from "react";

const Wrapper: FC<PropsWithChildren> = ({ children }) => <Fragment>{children}</Fragment>;

/**
 * This component is similar to `yieldLazyLoad` but it allows to suspense any `Promise` within your
 * returned component tree.
 *
 * Example:
 *
 * ```ts
 * function MyComponent() {
 *      const myPromise = useMemo(() => Promise.resolve(), []);
 *
 *      return (<YieldLazyLoad promise={myPromise}>
 *          I get rendered when promise got resolved.
 *      </YieldLazyLoad>);
 * }
 * ```
 */
const YieldLazyLoad: FC<
    PropsWithChildren<{ promise: Promise<any>; suspenseProbs?: Parameters<typeof yieldLazyLoad>[2] }>
> = ({ promise, children, suspenseProbs }) => {
    const MyPromiseYielded = useMemo(
        () =>
            yieldLazyLoad(
                (promise || Promise.resolve()).then(() => Wrapper),
                undefined,
                suspenseProbs,
            ),
        [promise],
    );
    return <MyPromiseYielded>{children}</MyPromiseYielded>;
};

export { YieldLazyLoad };
