import { compileMDX } from 'next-mdx-remote/rsc';
import matter from 'gray-matter';
import rehypeSlug from 'rehype-slug';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import remarkGfm from 'remark-gfm';
import { parseFrontmatter, safeParseFrontmatter } from './frontmatter';
import { remarkMermaid } from './remark-mermaid';
/**
 * Extract frontmatter from raw MDX content
 */ export function extractFrontmatter(source) {
    const { content, data } = matter(source);
    return {
        content,
        data
    };
}
/**
 * Extract headings from MDX content for table of contents
 */ export function extractHeadings(content) {
    const headingRegex = /^(#{1,6})\s+(.+)$/gm;
    const headings = [];
    let match;
    while((match = headingRegex.exec(content)) !== null){
        const level = match[1].length;
        const title = match[2].trim();
        // Generate slug from title (same logic as rehype-slug)
        const id = title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
        headings.push({
            id,
            title,
            level
        });
    }
    return headings;
}
/**
 * Compile MDX content with components and plugins
 */ export async function compileMDXContent(source, options = {}) {
    const { components = {}, scope = {}, validateFrontmatter = true } = options;
    // Extract frontmatter first
    const { content: mdxContent, data: rawFrontmatter } = extractFrontmatter(source);
    // Validate frontmatter if requested
    const frontmatter = validateFrontmatter ? parseFrontmatter(rawFrontmatter) : rawFrontmatter;
    // Extract headings for ToC
    const headings = extractHeadings(mdxContent);
    // Compile MDX
    const { content } = await compileMDX({
        source: mdxContent,
        components,
        options: {
            parseFrontmatter: false,
            mdxOptions: {
                remarkPlugins: [
                    remarkGfm,
                    remarkMermaid
                ],
                rehypePlugins: [
                    rehypeSlug,
                    [
                        rehypeAutolinkHeadings,
                        {
                            behavior: 'wrap'
                        }
                    ]
                ]
            },
            scope: {
                ...scope,
                frontmatter
            }
        }
    });
    return {
        content,
        frontmatter,
        headings
    };
}
/**
 * Quick compile for previews (less validation)
 */ export async function quickCompileMDX(source, components = {}) {
    const { content: mdxContent, data: frontmatter } = extractFrontmatter(source);
    const { content } = await compileMDX({
        source: mdxContent,
        components,
        options: {
            parseFrontmatter: false,
            mdxOptions: {
                remarkPlugins: [
                    remarkGfm,
                    remarkMermaid
                ],
                rehypePlugins: [
                    rehypeSlug
                ]
            }
        }
    });
    return {
        content,
        frontmatter
    };
}
/**
 * Validate MDX content without compiling (for linting)
 */ export function validateMDXContent(source) {
    const errors = [];
    const warnings = [];
    try {
        const { data } = extractFrontmatter(source);
        // Check frontmatter
        const frontmatterResult = safeParseFrontmatter(data);
        if (!frontmatterResult) {
            errors.push('Invalid frontmatter format');
        }
        // Check for common issues
        if (!data.title) {
            warnings.push('Missing title in frontmatter');
        }
        if (!data.description) {
            warnings.push('Missing description in frontmatter (recommended for SEO)');
        }
    } catch (error) {
        errors.push(`Parse error: ${error instanceof Error ? error.message : 'Unknown error'}`);
    }
    return {
        valid: errors.length === 0,
        errors,
        warnings
    };
}
