import DOMPurify from "isomorphic-dompurify";

/**
 * Minimal, dependency-free markdown → HTML for user content written in the
 * admin MarkdownEditor. Handles: headings (# through ###), paragraphs,
 * unordered and ordered lists, bold/italic inline, and [text](url) links.
 * Everything is DOMPurify-sanitised before return.
 *
 * For anything richer (tables, code blocks with syntax highlighting) swap in
 * `marked` or `remark` — kept minimal here to keep the bundle small.
 */
export function renderMarkdown(src: string): string {
  if (!src) return "";

  const escape = (s: string) =>
    s
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#39;");

  const inline = (line: string) => {
    let out = escape(line);
    // [text](url)
    out = out.replace(
      /\[([^\]]+)\]\(([^)\s]+)\)/g,
      (_m, text, url) =>
        `<a href="${url}" rel="noreferrer">${text}</a>`,
    );
    // **bold**
    out = out.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
    // *italic*
    out = out.replace(/(^|\s)\*([^*]+)\*/g, "$1<em>$2</em>");
    // `code`
    out = out.replace(/`([^`]+)`/g, "<code>$1</code>");
    return out;
  };

  const lines = src.replace(/\r\n/g, "\n").split("\n");
  const out: string[] = [];
  let i = 0;

  while (i < lines.length) {
    const line = lines[i];

    // Blank line
    if (/^\s*$/.test(line)) {
      i += 1;
      continue;
    }

    // Heading
    const h = line.match(/^(#{1,3})\s+(.*)$/);
    if (h) {
      const level = h[1].length;
      out.push(`<h${level}>${inline(h[2])}</h${level}>`);
      i += 1;
      continue;
    }

    // Unordered list
    if (/^\s*[-*]\s+/.test(line)) {
      const items: string[] = [];
      while (i < lines.length && /^\s*[-*]\s+/.test(lines[i])) {
        items.push(inline(lines[i].replace(/^\s*[-*]\s+/, "")));
        i += 1;
      }
      out.push(`<ul>${items.map((x) => `<li>${x}</li>`).join("")}</ul>`);
      continue;
    }

    // Ordered list
    if (/^\s*\d+\.\s+/.test(line)) {
      const items: string[] = [];
      while (i < lines.length && /^\s*\d+\.\s+/.test(lines[i])) {
        items.push(inline(lines[i].replace(/^\s*\d+\.\s+/, "")));
        i += 1;
      }
      out.push(`<ol>${items.map((x) => `<li>${x}</li>`).join("")}</ol>`);
      continue;
    }

    // Paragraph — gather consecutive non-empty, non-special lines
    const para: string[] = [];
    while (
      i < lines.length &&
      lines[i].trim() !== "" &&
      !/^(#{1,3})\s+/.test(lines[i]) &&
      !/^\s*[-*]\s+/.test(lines[i]) &&
      !/^\s*\d+\.\s+/.test(lines[i])
    ) {
      para.push(inline(lines[i]));
      i += 1;
    }
    out.push(`<p>${para.join("<br/>")}</p>`);
  }

  return DOMPurify.sanitize(out.join("\n"), {
    USE_PROFILES: { html: true },
    FORBID_TAGS: ["script", "style", "iframe", "form"],
    FORBID_ATTR: ["onerror", "onclick", "onload", "onmouseover"],
  });
}
