import { forwardRef, useImperativeHandle, useState } from "react";
import { createPortal, flushSync } from "react-dom";

/**
 * A helper component to render a single element to a container so we can subsequently read the DOM / HTML contents
 *
 * This is useful so we can render arbitrary React elements (blocks) in the correct context (used by `ReactRenderUtil`)
 */
export const ElementRenderer = forwardRef<
  (node: React.ReactNode, container: HTMLElement) => void
>((_props, ref) => {
  const [singleRenderData, setSingleRenderData] = useState<
    { node: React.ReactNode; container: HTMLElement } | undefined
  >();

  useImperativeHandle(
    ref,
    () => {
      return (node: React.ReactNode, container: HTMLElement) => {
        flushSync(() => {
          setSingleRenderData({ node, container });
        });

        // clear after it's been rendered to `container`
        setSingleRenderData(undefined);
      };
    },
    []
  );

  return (
    <>
      {singleRenderData &&
        createPortal(singleRenderData.node, singleRenderData.container)}
    </>
  );
});
