export type TocItem = { id: string; text: string; level: 2 | 3 };
export type ProcessedArticle = {
  html: string;
  toc: TocItem[];
  readingMinutes: number;
  wordCount: number;
};

const HEADING_RE = /<h([1-6])([^>]*)>([\s\S]*?)<\/h\1>/gi;

export function processArticle(rawHtml: string): ProcessedArticle {
  let minLevel = 6;
  for (const match of rawHtml.matchAll(HEADING_RE)) {
    const lvl = Number(match[1]);
    if (lvl < minLevel) minLevel = lvl;
  }
  if (minLevel > 6) minLevel = 3;
  const shift = Math.max(0, minLevel - 2);

  const slugs = new Map<string, number>();
  const toc: TocItem[] = [];

  const slugify = (text: string): string => {
    const base =
      text
        .toLowerCase()
        .replace(/<[^>]+>/g, "")
        .replace(/&[a-z]+;/gi, " ")
        .replace(/[^a-z0-9]+/g, "-")
        .replace(/^-+|-+$/g, "") || "section";
    const seen = slugs.get(base) || 0;
    slugs.set(base, seen + 1);
    return seen ? `${base}-${seen + 1}` : base;
  };

  const html = rawHtml.replace(
    HEADING_RE,
    (_match, levelStr: string, attrs: string, inner: string) => {
      const srcLevel = Number(levelStr);
      const shifted = Math.max(2, Math.min(6, srcLevel - shift));
      const textOnly = inner.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
      if (!textOnly) return `<h${shifted}${attrs}>${inner}</h${shifted}>`;
      const id = slugify(textOnly);
      if (shifted === 2 || shifted === 3) {
        toc.push({ id, text: textOnly, level: shifted as 2 | 3 });
      }
      const cleanedAttrs = attrs.replace(/\s*id="[^"]*"/i, "");
      return `<h${shifted} id="${id}"${cleanedAttrs}>${inner}</h${shifted}>`;
    }
  );

  let markedFirstParagraph = false;
  const htmlWithDropCap = html.replace(/<p(\s[^>]*)?>/i, (match) => {
    if (markedFirstParagraph) return match;
    markedFirstParagraph = true;
    if (/class="/.test(match)) {
      return match.replace(/class="([^"]*)"/, 'class="$1 blog-lead"');
    }
    return match.replace(/<p/, '<p class="blog-lead"');
  });

  const finalHtml = htmlWithDropCap;
  const plain = finalHtml.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
  const wordCount = plain ? plain.split(" ").length : 0;
  const readingMinutes = Math.max(1, Math.round(wordCount / 225));

  return { html: finalHtml, toc, readingMinutes, wordCount };
}
