import { useMemo } from "preact/hooks";
import DOMPurify from "dompurify";
import { marked } from "marked";
import { cn } from "@/lib/utils";

type MarkdownMode = "default" | "citationTokens";

type Props = {
  markdown: string;
  className?: string;
  mode?: MarkdownMode;
  resolveCitationIndex?: (href: string) => number | undefined;
};

function replaceMarkdownLinksWithCitationTokens(markdown: string, resolveCitationIndex?: (href: string) => number | undefined) {
  if (!resolveCitationIndex) return markdown;
  return markdown.replace(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g, (_full, _label, href) => {
    const index = resolveCitationIndex(href);
    if (!index) return "";
    return `<span class="md-cite-token">[${index}]</span>`;
  });
}

function renderMarkdown(markdown: string) {
  const rawHtml = marked.parse(markdown, { gfm: true, breaks: true }) as string;
  return DOMPurify.sanitize(rawHtml, { ADD_ATTR: ["class", "target", "rel"] });
}

export function MarkdownContent({ markdown, className, mode = "default", resolveCitationIndex }: Props) {
  const html = useMemo(() => {
    const prepared =
      mode === "citationTokens" ? replaceMarkdownLinksWithCitationTokens(markdown, resolveCitationIndex) : markdown;
    return renderMarkdown(prepared);
  }, [markdown, mode, resolveCitationIndex]);

  return <div className={cn("md-content", className)} dangerouslySetInnerHTML={{ __html: html }} />;
}
