import { getCollection } from "astro:content";
import { SITE, getAuthor, sortedPosts } from "../lib/blog-data.js";

const BASE_URL = SITE.url || "";

const esc = (value) =>
  value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");

// Wrap arbitrary text safely in a CDATA section.
const cdata = (s) => `<![CDATA[${String(s).replace(/]]>/g, "]]]]><![CDATA[>")}]]>`;

// Convert MDX/Markdown body to plain text (text only — strip formatting, keep link text).
function mdToText(md = "") {
  return md
    .replace(/^---[\s\S]*?---\s*/, "") // strip frontmatter if present
    .replace(/^import\s.*$/gm, "") // strip MDX import lines
    .replace(/`{1,3}([^`]*)`{1,3}/g, "$1") // inline code
    .replace(/!\[[^\]]*\]\([^)]*\)/g, "") // images
    .replace(/\[([^\]]+)\]\([^)]*\)/g, "$1") // links → text
    .replace(/^\s{0,3}#{1,6}\s+/gm, "") // headings
    .replace(/^\s{0,3}>\s?/gm, "") // blockquotes
    .replace(/^\s{0,3}([-*+])\s+/gm, "") // unordered list markers
    .replace(/^\s{0,3}\d+\.\s+/gm, "") // ordered list markers
    .replace(/^\s*[-*_]{3,}\s*$/gm, "") // horizontal rules
    .replace(/(\*\*|__)(.*?)\1/g, "$2") // bold
    .replace(/(\*|_)(.*?)\1/g, "$2") // italic
    .replace(/<[^>]+>/g, "") // any stray HTML/JSX tags
    .replace(/\n{3,}/g, "\n\n") // collapse blank lines
    .trim();
}

export async function GET() {
  const bodyBySlug = Object.fromEntries((await getCollection("blog")).map((e) => [e.id, e.body || ""]));

  const items = (await sortedPosts()).map((post) => {
    const link = `${BASE_URL}/blog/${post.slug}`;
    const author = getAuthor(post.author);
    const fullText = mdToText(bodyBySlug[post.slug]);
    return [
      "    <item>",
      `      <title>${esc(post.title)}</title>`,
      `      <link>${link}</link>`,
      `      <guid isPermaLink="true">${link}</guid>`,
      `      <pubDate>${new Date(post.date).toUTCString()}</pubDate>`,
      author ? `      <dc:creator>${esc(author.name)}</dc:creator>` : "",
      `      <description>${esc(post.excerpt)}</description>`,
      `      <content:encoded>${cdata(fullText)}</content:encoded>`,
      "    </item>",
    ]
      .filter(Boolean)
      .join("\n");
  });

  const xml = [
    '<?xml version="1.0" encoding="UTF-8"?>',
    '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">',
    "  <channel>",
    `    <title>${esc(SITE.name)}</title>`,
    `    <link>${BASE_URL}/</link>`,
    `    <description>${esc(SITE.description)}</description>`,
    "    <language>en-us</language>",
    ...items,
    "  </channel>",
    "</rss>",
  ].join("\n");

  return new Response(xml, {
    headers: {
      "Content-Type": "application/rss+xml; charset=utf-8",
      "Cache-Control": "public, max-age=3600",
    },
  });
}
