type MarkdownPost = {
  frontmatter: {
    slug: string;
    title: string;
    summary?: string;
    status?: string;
    tags?: string[];
    created_at?: string;
    published_at?: string;
    updated_at?: string;
  };
  Content: any;
};

export type Post = MarkdownPost['frontmatter'] & {
  url: string;
  date: string;
  tags: string[];
  Content: any;
};

export type TagSummary = {
  name: string;
  slug: string;
  count: number;
};

export type ArchiveYear = {
  year: string;
  posts: Post[];
};

export const POSTS_PER_PAGE = 6;

function isPublicStatus(status?: string) {
  return status === 'published' || status === 'archived';
}

export function getPublishedPosts(): Post[] {
  const modules = import.meta.glob('../../../../content/posts/*.md', { eager: true });

  return Object.values(modules)
    .map((post) => {
      const frontmatter = (post as MarkdownPost).frontmatter;
      const Content = (post as MarkdownPost).Content;
      return {
        ...frontmatter,
        Content,
        url: `/posts/${frontmatter.slug}/`,
        date: frontmatter.created_at ?? frontmatter.published_at ?? frontmatter.updated_at ?? '',
        tags: frontmatter.tags ?? []
      };
    })
    .filter((post) => isPublicStatus(post.status))
    .sort((a, b) => String(b.date).localeCompare(String(a.date)));
}

export function getPaginatedPosts(posts: Post[], page: number, perPage = POSTS_PER_PAGE): Post[] {
  const start = (page - 1) * perPage;
  return posts.slice(start, start + perPage);
}

export function getTotalPages(posts: Post[], perPage = POSTS_PER_PAGE): number {
  return Math.max(1, Math.ceil(posts.length / perPage));
}

export function tagSlug(tag: string): string {
  return encodeURIComponent(tag.trim().toLowerCase().replace(/\s+/g, '-'));
}

export function getTagSummaries(): TagSummary[] {
  const counts = new Map<string, TagSummary>();

  for (const post of getPublishedPosts()) {
    for (const tag of post.tags) {
      const name = tag.trim();
      if (!name) {
        continue;
      }

      const slug = tagSlug(name);
      const current = counts.get(slug);
      if (current) {
        current.count += 1;
      } else {
        counts.set(slug, { name, slug, count: 1 });
      }
    }
  }

  return [...counts.values()].sort((a, b) => a.name.localeCompare(b.name));
}

export function getPostsByTag(slug: string): Post[] {
  return getPublishedPosts().filter((post) => post.tags.some((tag) => tagSlug(tag) === slug));
}

export function getArchiveYears(): ArchiveYear[] {
  const years = new Map<string, Post[]>();

  for (const post of getPublishedPosts()) {
    const year = post.date ? String(new Date(post.date).getFullYear()) : 'Undated';
    years.set(year, [...(years.get(year) ?? []), post]);
  }

  return [...years.entries()]
    .sort(([a], [b]) => b.localeCompare(a))
    .map(([year, posts]) => ({ year, posts }));
}
