import { defineCollection, defineConfig } from "@content-collections/core";
import { compileMDX } from "@content-collections/mdx";
import GithubSlugger from "github-slugger";
import rehypeSlug from "rehype-slug";
import remarkGfm from "remark-gfm";
import { z } from "zod";

// Author registry (mirrored from lib/authors.ts for build-time resolution)
const AUTHORS: Record<string, { name: string; avatar: string }> = {
  "joel-lassalle": {
    name: "Joël Lassalle",
    avatar: "/blog/joel_lassalle.webp",
  },
};
function resolveAuthor(id: string) {
  return AUTHORS[id] ?? AUTHORS["joel-lassalle"];
}

// Valid blog categories for SEO-friendly URLs
const VALID_CATEGORIES = [
  "actualites",
  "guides",
  "reglementation",
  "cas-clients",
] as const;

// Calculate reading time (average 200 words per minute)
function calculateReadingTime(content: string): number {
  const words = content.trim().split(/\s+/).length;
  return Math.max(1, Math.ceil(words / 200));
}

// Extract headings for TOC (h2 and h3 only)
// Uses github-slugger to match rehype-slug's algorithm exactly
function extractToc(
  content: string,
): Array<{ level: number; text: string; slug: string }> {
  const slugger = new GithubSlugger();
  const headingRegex = /^(#{2,3})\s+(.+)$/gm;
  const toc: Array<{ level: number; text: string; slug: string }> = [];
  let match;

  while ((match = headingRegex.exec(content)) !== null) {
    const level = match[1].length;
    const text = match[2].trim();
    // github-slugger handles duplicates automatically
    const slug = slugger.slug(text);

    toc.push({ level, text, slug });
  }

  return toc;
}

const blogs = defineCollection({
  name: "blogs",
  directory: "data/blogs",
  include: "*.mdx",
  schema: z.object({
    // Explicit content property (was implicit before content-collections 0.12).
    // Filled by the frontmatter parser with the MDX body (text after the
    // frontmatter YAML). Consumed in transform() via document.content.
    content: z.string(),
    title: z.string(),
    date: z.string(),
    authorId: z.string().default("joel-lassalle"),
    description: z.string(),
    image: z.string(),
    categories: z.array(z.string()),
    // SEO fields
    category: z.enum(VALID_CATEGORIES),
    seoTitle: z.string().optional(),
    lastmod: z.string().optional(),
    imageAlt: z.string().optional(),
    keywords: z.array(z.string()).optional(),
    canonical: z.string().optional(),
    updatedAt: z.string().optional(),
    // Publishing control
    draft: z.boolean().default(false),
    featured: z.boolean().default(false),

    // E-E-A-T fields
    reviewer: z.string().optional(),

    // Semantic fields for LLM
    topics: z.array(z.string()).optional(),
    audience: z.enum(["debutant", "intermediaire", "expert", "cto"]).optional(),
    relatedPosts: z.array(z.string()).optional(),
    mentions: z.array(z.string()).optional(),

    // FAQ for rich snippets
    faqs: z
      .array(
        z.object({
          question: z.string(),
          answer: z.string(),
        }),
      )
      .optional(),

    // HowTo structured data (schema.org)
    howTo: z
      .object({
        description: z.string(),
        totalTime: z.string().optional(),
        estimatedCost: z.string().optional(),
        steps: z.array(
          z.object({
            name: z.string(),
            text: z.string(),
          }),
        ),
      })
      .optional(),
  }),
  transform: async (document, context) => {
    const body = await compileMDX(context, document, {
      remarkPlugins: [remarkGfm],
      rehypePlugins: [
        // rehypeSlug adds id="" to every heading for in-page anchor
        // navigation (URL #fragment) and TOC. No <a> is injected.
        // Pure <h1>/<h2>/<h3> markup preserved for SEO and accessibility.
        rehypeSlug,
      ],
    });

    const slug = document._meta.path;
    const readingTime = calculateReadingTime(document.content);
    const toc = extractToc(document.content);
    const resolved = resolveAuthor(document.authorId);

    return {
      ...document,
      // Computed fields from author registry
      author: resolved.name,
      authorAvatar: resolved.avatar,
      body,
      slug,
      readingTime,
      toc,
    };
  },
});

export default defineConfig({
  // `collections` was renamed to `content` in content-collections 0.x
  // (deprecation: https://content-collections.dev/docs/deprecations/config-collections-property).
  content: [blogs],
});
