import rss from "@astrojs/rss";
import type { APIRoute } from "astro";
import { getCollection } from "astro:content";
import { blogFeedItem, gameFeedItem, storyFeedItem, type EntryWithPubDate } from "@utils/feed";

const MAX_ITEMS = 8;

export const GET: APIRoute = async ({ site }) => {
  if (!site) {
    throw new Error("site is required.");
  }
  const stories = (
    (await getCollection(
      "stories",
      (story) => !story.data.isDraft && story.data.pubDate,
    )) as EntryWithPubDate<"stories">[]
  )
    .sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
    .slice(0, MAX_ITEMS);
  const games = (
    (await getCollection("games", (game) => !game.data.isDraft && game.data.pubDate)) as EntryWithPubDate<"games">[]
  )
    .sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
    .slice(0, MAX_ITEMS);
  const posts = (
    (await getCollection("blog", (post) => !post.data.isDraft && post.data.pubDate)) as EntryWithPubDate<"blog">[]
  )
    .sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
    .slice(0, MAX_ITEMS);

  return rss({
    title: "Gallery | Bad Manners",
    description: "Stories, games, and more by Bad Manners.",
    site,
    xmlns: { atom: "http://www.w3.org/2005/Atom" },
    customData: `<link href="${site}" rel="alternate" type="text/html" /><atom:link href="${new URL("feed.xml", site)}" rel="self" type="application/rss+xml" />`,
    items: await Promise.all(
      [
        stories.map(({ data, slug, render }) => ({
          date: data.pubDate,
          fn: async () => storyFeedItem(site, data, slug, (await render()).Content),
        })),
        games.map(({ data, slug, render }) => ({
          date: data.pubDate,
          fn: async () => gameFeedItem(site, data, slug, (await render()).Content),
        })),
        posts.map(({ data, slug, render }) => ({
          date: data.pubDate,
          fn: async () => blogFeedItem(site, data, slug, (await render()).Content),
        })),
      ]
        .flat()
        .sort((a, b) => b.date.getTime() - a.date.getTime())
        .slice(0, MAX_ITEMS)
        .map((value) => value.fn()),
    ),
  });
};
