// ponytail: minimal Markdown → HTML for session notes/summaries. Renders the
// 80% a DM actually uses (headings, bold/italic, lists, code, paragraphs) in
// ~40 lines. No dependency. Escapes HTML first so LLM output can't inject.
// Upgrade path: swap for @uiw/react-md-editor if you need tables/images/GFM.

function escapeHtml(s: string): string {
  return s
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

/** Render a subset of Markdown to HTML. Input is treated as untrusted. */
export function renderMarkdown(md: string): string {
  const lines = md.split("\n");
  const html: string[] = [];
  let inList = false;
  const closeList = () => { if (inList) { html.push("</ul>"); inList = false; } };

  for (const raw of lines) {
    const line = raw.trimEnd();
    if (!line.trim()) { closeList(); continue; }

    const h = line.match(/^(#{1,6})\s+(.*)$/);
    if (h) {
      closeList();
      const level = h[1].length;
      html.push(`<h${level}>${inline(h[2])}</h${level}>`);
      continue;
    }
    const li = line.match(/^[-*+]\s+(.*)$/);
    if (li) {
      if (!inList) { html.push("<ul>"); inList = true; }
      html.push(`<li>${inline(li[1])}</li>`);
      continue;
    }
    const ol = line.match(/^\d+[.)]\s+(.*)$/);
    if (ol) {
      // ponytail: render ordered items as an unordered list too — keeping it
      // one-element-type saves a state machine. A DM reading notes won't mind.
      if (!inList) { html.push("<ul>"); inList = true; }
      html.push(`<li>${inline(ol[1])}</li>`);
      continue;
    }
    closeList();
    html.push(`<p>${inline(line)}</p>`);
  }
  closeList();
  return html.join("\n");
}

// inline formatting: **bold**, *italic*, `code`, [text](url).
function inline(s: string): string {
  let out = escapeHtml(s);
  out = out.replace(/`([^`]+)`/g, '<code>$1</code>');
  out = out.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
  out = out.replace(/\*([^*]+)\*/g, "<em>$1</em>");
  out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>');
  return out;
}

// (self-check lives in the repo's node test mirror; this module is pure).