import {
  createElement,
  useEffect,
  useRef,
  ComponentPropsWithoutRef,
} from "react";

interface IProps
  extends Omit<ComponentPropsWithoutRef<"div">, "dangerouslySetInnerHTML"> {
  html: string;
  allowRerender?: boolean;
}

/**
 * [`dangerouslySetInnerHTML`](https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html)
 * but also runs `<script>` tags.
 *
 * Stolen from https://github.com/christo-pr/dangerously-set-html-content
 */
export function DangerousContent({ html, allowRerender, ...props }: IProps) {
  const parentRef = useRef<HTMLElement>(null);
  const isFirstRender = useRef<boolean>(true);

  useEffect(() => {
    if (!html || !parentRef.current) {
      throw new Error("`html` prop can't be null");
    }

    if (!isFirstRender.current) {
      return;
    }

    isFirstRender.current = Boolean(allowRerender);

    // Create a 'tiny' document and parse the html string
    const slotHtml = document.createRange().createContextualFragment(html);
    // Clear the container
    parentRef.current.innerHTML = "";
    // Append the new content
    parentRef.current.appendChild(slotHtml);
  }, [html, parentRef]);

  return createElement("div", { ...props, ref: parentRef });
}
