type MarkdownModule = {
  frontmatter: Record<string, unknown>;
  Content: unknown;
  rawContent?: () => string;
  file?: string;
};

export type BlogPost = MarkdownModule & {
  title: string;
  slug: string;
  date: Date;
  dateText: string;
  tags: string[];
  categories: string[];
  summary: string;
  href: string;
};

const modules = import.meta.glob<MarkdownModule>('/source/_posts/**/*.md', { eager: true });

function asArray(value: unknown): string[] {
  if (Array.isArray(value)) return value.map(String).filter(Boolean);
  if (typeof value === 'string' && value.trim()) return [value.trim()];
  return [];
}

function toDate(value: unknown): Date {
  if (value instanceof Date) return value;
  if (typeof value === 'string' || typeof value === 'number') {
    const date = new Date(value);
    if (!Number.isNaN(date.valueOf())) return date;
  }
  return new Date(0);
}

function formatDate(date: Date): string {
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  }).format(date);
}

function fallbackSlug(path: string): string {
  return path
    .split('/')
    .pop()
    ?.replace(/\.md$/, '')
    .toLowerCase() ?? 'post';
}

function makeSummary(module: MarkdownModule): string {
  const explicit = module.frontmatter.summary ?? module.frontmatter.description;
  if (typeof explicit === 'string' && explicit.trim()) return explicit.trim();

  const raw = module.rawContent?.() ?? '';
  return raw
    .replace(/```[\s\S]*?```/g, '')
    .replace(/<[^>]+>/g, '')
    .replace(/[#>*_`~\-\[\]\(\)]/g, '')
    .replace(/\s+/g, ' ')
    .trim()
    .slice(0, 120);
}

export function getAllPosts(): BlogPost[] {
  return Object.entries(modules)
    .map(([path, module]) => {
      const date = toDate(module.frontmatter.date);
      const slug = String(module.frontmatter.abbrlink ?? fallbackSlug(path));
      const title = String(module.frontmatter.title ?? slug);

      return {
        ...module,
        title,
        slug,
        date,
        dateText: formatDate(date),
        tags: asArray(module.frontmatter.tags),
        categories: asArray(module.frontmatter.categories),
        summary: makeSummary(module),
        href: `/posts/${slug}/`,
      };
    })
    .sort((a, b) => b.date.valueOf() - a.date.valueOf());
}

export function getAllTags(): string[] {
  return [...new Set(getAllPosts().flatMap((post) => post.tags))].sort((a, b) => a.localeCompare(b, 'zh-CN'));
}

export function getAllCategories(): string[] {
  return [...new Set(getAllPosts().flatMap((post) => post.categories))].sort((a, b) => a.localeCompare(b, 'zh-CN'));
}
