<template>
  <section id="blog" class="BlogOverview content">
    <h1>Blogfussel - für mehr Fussel im Blog</h1>
    <p>Hey! Hier sammel ich alles, was mir so durch den Kopf geht - von handfesten Tutorials und Code-Snippets über Freelancing-Stories
      bis hin zu News meiner Apps und random Gedanken. Manchmal ausführlich, manchmal nur kurz angerissen.</p>

    <main class="margin-top">
      <ul class="category-list">
        <li>
          <NuxtLink class="inline-flex-row gap-sm side" to="/blog">
            <span class="chip"
                  :class="{ 'dark' : route.query.category && Object.keys(allCategoriesAndCount).includes(route.query.category as string)}">Alle {{
                articles?.length
              }}</span>
          </NuxtLink>
        </li>
        <li v-for="(count, category) in allCategoriesAndCount">
          <NuxtLink class="inline-flex-row gap-sm side" :to="`?category=${category}`">
            <span class="chip" :class="{ 'dark' : category !== route.query.category}"><BlogCategory :name="category"/> {{ count }}</span>
          </NuxtLink>
        </li>
      </ul>
      <div class="grid margin-top-middle article-overview">
        <BlogCard v-for="article in allPosts" v-bind="article"/>
        <div v-if="allPosts.length < 2"/>
        <div v-if="allPosts.length < 3"/>
      </div>
    </main>
  </section>
</template>

<script setup lang="ts">
import type { BlogCollectionItem } from '@nuxt/content'
import type { BlogCard, Category } from '../../components/Blog/types'

const route = useRoute()

const { data: articles } = await useAsyncData('articles', () => queryCollection('blog')
  .where('date', '<', tomorrow(new Date()))
  .order('date', 'DESC')
  .all(),
)

const firstTen = computed<BlogCard[]>(() => {
  if (route.query.category && Object.keys(allCategoriesAndCount.value).includes(route.query.category as Category)) {
    return (articles.value?.filter(article => article.category === route.query.category).slice(0, 10) ?? []).map(makeBlogCard)
  }
  return (articles.value?.slice(0, 10) ?? []).map(makeBlogCard)
})

const { data: externalPostsRaw } = useFetch('/api/external-posts', { method: 'POST' })

const externalPosts = computed<BlogCard[]>(() => externalPostsRaw.value?.flatMap(externalBlog => {
  return externalBlog.posts.map(post => ({
    title: post.title,
    description: post.excerpt,
    image: post.thumbnail,
    date: post.date,
    link: post.url,
    category: 'extern',
    author: externalBlog.author,
  }))
}) ?? [])

const allPosts = computed<BlogCard[]>(() => {
  const allPosts = [...firstTen.value, ...externalPosts.value]
  allPosts.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
  if (route.query.category && Object.keys(allCategoriesAndCount.value).includes(route.query.category as Category)) {
    return allPosts.filter(article => article.category === route.query.category)
  }
  return allPosts
})

const allCategoriesAndCount = computed<Record<Category, number>>(() => {
  const categories = {} as Record<Category, number>
  articles.value?.forEach(article => {
    const category = article.category as Category
    if (category) {
      categories[category] = (categories[category] ?? 0) + 1
    }
  })
  categories['extern'] = externalPosts.value?.length ?? 0
  return categories
})

const makeBlogCard = (article: BlogCollectionItem): BlogCard => ({
  title: article.title,
  description: article.description,
  image: article.thumbnail as string,
  date: article.date as string,
  link: article.path,
  category: article.category as Category,
  author: article.author as { name: string, image: string },
})

useHead({
  link: [
    { rel: 'alternate', type: 'application/rss+xml', href: '/blog/rss.xml', title: 'blogfussel' },
  ],
})
</script>