import clsx from "clsx";
import * as React from "react";
import { useSafeLayoutEffect } from "../../hooks";
import { Prose } from "../Prose";
import * as styles from "./styles.module.css";

interface TextProps extends React.ComponentPropsWithoutRef<"span"> {
  "data-id": string;
  value: string;
}

function _RawHTML({
  value,
  dangerouslySetInnerHTML,
  className,
  ...props
}: TextProps) {
  const ref = React.useRef<HTMLDivElement>(null);
  const firstRender = React.useRef(true);
  const isSSR = typeof document === "undefined";
  const html = value?.trim() ?? "";

  // Html content that includes scripts tags will not execute unless the
  // component is SSR'd or the component uses "createContextualFragment".
  // Here we skip the hydration step if the component is SSR'd.
  // However, if the html value changes, then we do need to update the dom again
  useSafeLayoutEffect(() => {
    if (
      firstRender.current
        ? html && ref.current && !ref.current.hasAttribute("data-ssr")
        : ref.current
    ) {
      const slotHtml = document.createRange().createContextualFragment(html); // Create a 'tiny' document and parse the html string
      ref.current!.replaceChildren(slotHtml); // Replace the new content
      ref.current!.setAttribute("data-ssr", "true");
      if (firstRender.current) {
        document.dispatchEvent(
          new Event("Brevity|scripts-ready", { bubbles: true }),
        );
      }
      firstRender.current = false;
    }
  }, [html]);

  return (
    <Prose
      as="div"
      {...props}
      suppressHydrationWarning
      ref={ref}
      className={clsx(styles.raw, className)}
      data-ssr={isSSR ? true : undefined}
      wysiwyg={html}
    />
  );
}

export const RawHTML = React.memo(_RawHTML);
