export type Heading = { id: string; text: string };

/**
 * Deterministic heading slug: strips accents, lowercases, collapses any run of
 * non-alphanumeric characters to a single hyphen. Shared by the MDX `<h2>`
 * renderer (which sets the `id`) and the table of contents (which links to it),
 * so the two always agree.
 */
export function slugifyHeading(text: string): string {
  return text
    .normalize("NFKD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

function stripInlineMarkdown(text: string): string {
  return text
    .replace(/\[(.+?)\]\((.+?)\)/g, "$1") // [label](url) → label
    .replace(/\*\*(.+?)\*\*/g, "$1") // bold
    .replace(/\*(.+?)\*/g, "$1") // italic
    .replace(/`(.+?)`/g, "$1") // inline code
    .trim();
}

/**
 * Pulls the `## ` headings from a raw MDX body in document order, returning the
 * same slug/id the renderer will use plus the cleaned display text.
 */
export function extractHeadings(body: string): Heading[] {
  const headings: Heading[] = [];
  const regex = /^##\s+(.+)$/gm;
  let match = regex.exec(body);
  while (match !== null) {
    const text = stripInlineMarkdown(match[1].trim());
    if (text.length > 0) {
      headings.push({ id: slugifyHeading(text), text });
    }
    match = regex.exec(body);
  }
  return headings;
}
