import { getCollection } from 'astro:content';

export type Entry = {
  type: 'review' | 'post' | 'finds';
  id: string;
  href: string;
  date: Date;
  category: string;
  tags: string[];
  primary: string;
  secondary?: string;
};

export async function getAllEntries(): Promise<Entry[]> {
  const reviews = await getCollection('reviews');
  const posts = await getCollection('posts');
  const findsPosts = await getCollection('finds');

  const r: Entry[] = reviews.map((e) => ({
    type: 'review',
    id: e.id,
    href: `/reviews/${e.id}/`,
    date: e.data.date,
    category: e.data.category,
    tags: e.data.tags,
    primary: e.data.name,
    secondary: e.data.subtitle,
  }));

  const p: Entry[] = posts.map((e) => ({
    type: 'post',
    id: e.id,
    href: `/posts/${e.id}/`,
    date: e.data.date,
    category: e.data.category,
    tags: e.data.tags,
    primary: e.data.title,
  }));

  const f: Entry[] = findsPosts.map((e) => ({
    type: 'finds',
    id: e.id,
    href: `/finds/${e.id}/`,
    date: e.data.date,
    category: e.data.category,
    tags: e.data.tags,
    primary: e.data.title,
    secondary: e.data.blurb,
  }));

  return [...r, ...p, ...f].sort((a, b) => b.date.valueOf() - a.date.valueOf());
}

export type SiteStats = {
  total: number;
  lastUpdated: Date | null;
  reviews: number;
  finds: number;
  posts: number;
  lists: number;
};

let statsCache: Promise<SiteStats> | null = null;

export function getSiteStats(): Promise<SiteStats> {
  if (!statsCache) statsCache = computeSiteStats();
  return statsCache;
}

async function computeSiteStats(): Promise<SiteStats> {
  const entries = await getAllEntries();
  const findItems = await getCollection('find');
  const reviews = entries.filter((e) => e.type === 'review').length;
  const finds = findItems.length;
  const posts = entries.filter((e) => e.type === 'post').length;
  const lists = entries.filter((e) => e.type === 'finds').length;
  const allDates = [
    ...entries.map((e) => e.date),
    ...findItems.map((f) => f.data.date),
  ].sort((a, b) => b.valueOf() - a.valueOf());
  return {
    total: reviews + finds + posts + lists,
    lastUpdated: allDates[0] ?? null,
    reviews,
    finds,
    posts,
    lists,
  };
}
