---
import { getCollection } from "astro:content";
import { slug } from "github-slugger";
import GalleryLayout from "@layouts/GalleryLayout.astro";
import { markdownToPlaintext } from "@utils/markdown_to_plaintext";
import { DEFAULT_LANG } from "@i18n";

interface Tag {
  id: string;
  name: string;
  description?: string;
}

const [stories, games, tagCategories, seriesCollection] = await Promise.all([
  getCollection("stories"),
  getCollection("games"),
  getCollection("tag-categories"),
  getCollection("series"),
]);
const uncategorizedTagsSet = new Set<string>();
const draftOnlyTagsSet = new Set<string>();
[stories, games].flat().forEach(({ data: { isDraft, tags } }) => {
  if (isDraft) {
    tags.forEach((tag) => draftOnlyTagsSet.add(tag));
  } else {
    tags.forEach((tag) => uncategorizedTagsSet.add(tag));
  }
});
// Tags from published content shouldn't be included in drafts-only set
uncategorizedTagsSet.forEach((tag) => draftOnlyTagsSet.delete(tag));

const uniqueSlugs = new Set<string>();
const categorizedTags = tagCategories
  .sort((a, b) => {
    if (a.data.index === b.data.index) {
      throw new Error(`Found tag categories with same index value ${a.data.index} ("${a.id}", "${b.id}")`);
    }
    return a.data.index - b.data.index;
  })
  .map((category) => {
    const tagList = category.data.tags.map<Tag>(({ name, description }) => {
      description =
        description &&
        markdownToPlaintext(typeof description === "object" ? description[DEFAULT_LANG] : description).replaceAll(
          /\n+/g,
          " ",
        );
      const tag = typeof name === "string" ? name : name.en;
      return { id: slug(tag), name: tag, description };
    });
    tagList.forEach(({ id, name }) => {
      if (uniqueSlugs.has(id)) {
        throw new Error(`Duplicated tag "${name}" found in multiple tag-categories entries`);
      }
      uniqueSlugs.add(id);
    });
    return {
      name: category.data.name,
      id: slug(category.data.name),
      tags: tagList.filter(({ name }) => {
        if (draftOnlyTagsSet.has(name)) {
          // console.log(`Omitting draft-only tag "${name}"`);
          return false;
        }
        uncategorizedTagsSet.delete(name);
        return true;
      }),
    };
  });

if (uncategorizedTagsSet.size > 0) {
  const tagList = [...uncategorizedTagsSet];
  console.warn("WARNING: The following tags have no category:", tagList);
  // categorizedTags.push(["Uncategorized tags", "others", tagList]);
}
---

<GalleryLayout pageTitle="Tags">
  <Fragment slot="head">
    <meta property="og:description" content="Bad Manners || Find all content with a specific tag." />
    <meta name="description" content="Find all content by Bad Manners with a specific tag." />
  </Fragment>
  <h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">All available tags</h1>
  <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
  <section class="my-2" aria-labelledby="category-series">
    <h2 id="category-series" class="p-2 text-xl font-semibold text-stone-800 dark:text-stone-100">Series</h2>
    <ul class="list-disc pl-8">
      {
        seriesCollection.map((series) => (
          <li>
            <a class="text-link underline" href={series.data.link}>
              {series.data.name}
            </a>
          </li>
        ))
      }
    </ul>
  </section>
  {
    categorizedTags.map(({ name: category, id: categoryId, tags: tagList }) =>
      tagList.length > 0 ? (
        <section class="my-2" aria-labelledby={`category-${categoryId}`}>
          <h2 id={`category-${categoryId}`} class="p-2 text-xl font-semibold text-stone-800 dark:text-stone-100">
            {category}
          </h2>
          <ul class="flex max-w-3xl flex-wrap gap-x-2 gap-y-3 px-3">
            {tagList.map(({ id, name, description }) => (
              <li>
                <a
                  class="rounded-full bg-bm-300 px-3 py-1 text-sm text-black shadow-sm hover:underline focus:underline dark:bg-green-700 dark:text-white"
                  href={`/tags/${id}`}
                  title={description}
                  data-tooltip
                >
                  {name}
                </a>
              </li>
            ))}
          </ul>
        </section>
      ) : null,
    )
  }
</GalleryLayout>
