import { clsx } from 'clsx';
import React, { useMemo } from 'react';
import { Parser, Renderer } from "./core";
import DebugPanel from "./DebugPanel";
import { useStreaming } from "./hooks";
import { resolveTailContent } from "./utils/tail";
import "./index.css";
const XMarkdown = /*#__PURE__*/React.memo(props => {
  const {
    streaming,
    config,
    components,
    paragraphTag,
    content,
    children,
    rootClassName,
    className,
    style,
    openLinksInNewTab,
    dompurifyConfig,
    protectCustomTagNewlines,
    escapeRawHtml,
    debug
  } = props;
  const tailContent = useMemo(() => resolveTailContent(streaming?.tail), [streaming?.tail]);
  const TailComponent = typeof streaming?.tail === 'object' ? streaming.tail.component : undefined;
  const shouldShowTail = !!streaming?.hasNextChunk && tailContent;

  // ============================ style ============================
  const mergedCls = clsx('x-markdown', rootClassName, className);

  // ============================ Streaming ============================
  const output = useStreaming(content || children || '', {
    streaming,
    components
  });

  // ============================ Merge components with xmd-tail ============================
  const mergedComponents = useMemo(() => {
    if (!shouldShowTail) {
      return components;
    }
    const TailElement = TailComponent ? ( /*#__PURE__*/React.createElement(TailComponent, {
      content: tailContent
    })) : /*#__PURE__*/React.createElement("span", {
      className: "xmd-tail"
    }, tailContent);
    return {
      ...components,
      'xmd-tail': () => TailElement
    };
  }, [shouldShowTail, components, TailComponent, tailContent]);

  // ============================ Render ============================
  const parser = useMemo(() => new Parser({
    markedConfig: config,
    paragraphTag,
    openLinksInNewTab,
    components: mergedComponents,
    protectCustomTagNewlines,
    escapeRawHtml
  }), [config, paragraphTag, openLinksInNewTab, mergedComponents, protectCustomTagNewlines, escapeRawHtml]);
  const renderer = useMemo(() => new Renderer({
    components: mergedComponents,
    dompurifyConfig,
    streaming
  }), [mergedComponents, dompurifyConfig, streaming]);
  const htmlString = useMemo(() => {
    if (!output) {
      return '';
    }
    return parser.parse(output, {
      injectTail: !!shouldShowTail
    });
  }, [output, parser, shouldShowTail]);
  const renderedContent = useMemo(() => htmlString ? renderer.render(htmlString) : null, [htmlString, renderer]);
  if (!output) {
    return null;
  }
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    className: mergedCls,
    style: style
  }, renderedContent), debug ? /*#__PURE__*/React.createElement(DebugPanel, null) : null);
});
if (process.env.NODE_ENV !== 'production') {
  XMarkdown.displayName = 'XMarkdown';
}
export default XMarkdown;