import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const _filename = typeof __filename !== 'undefined'
    ? __filename
    : (typeof import.meta !== 'undefined' && import.meta.url ? fileURLToPath(import.meta.url) : '');
const _dirname = typeof __dirname !== 'undefined'
    ? __dirname
    : (_filename ? path.dirname(_filename) : '');
/**
 * Provider for accessing n8n documentation
 */
export class DocsProvider {
    docs = null;
    docsPath;
    constructor(customDocsPath) {
        if (customDocsPath) {
            this.docsPath = customDocsPath;
        }
        else {
            this.docsPath = path.resolve(_dirname, '../assets/n8n-docs-complete.json');
        }
    }
    /**
     * Load documentation
     */
    loadDocs() {
        if (this.docs)
            return;
        if (!fs.existsSync(this.docsPath)) {
            throw new Error(`Documentation not found at ${this.docsPath}. ` +
                `Please run the build process: npm run build in packages/agent-cli`);
        }
        try {
            const content = fs.readFileSync(this.docsPath, 'utf-8');
            this.docs = JSON.parse(content);
        }
        catch (error) {
            throw new Error(`Failed to load documentation: ${error.message}. ` +
                `The file may be corrupted. Try rebuilding: npm run build in packages/agent-cli`);
        }
    }
    /**
     * Search documentation pages
     */
    searchDocs(query, options = {}) {
        this.loadDocs();
        if (!this.docs)
            return [];
        const queryLower = query.toLowerCase();
        // Normalization for accented characters (e.g. "génération" -> "generation")
        const queryClean = queryLower.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
        const queryTerms = queryClean.split(/\s+/).filter(t => t.length > 2);
        const results = [];
        for (const page of this.docs.pages) {
            // Apply filters
            if (options.category && page.category !== options.category)
                continue;
            if (options.complexity && page.metadata.complexity !== options.complexity)
                continue;
            if (options.hasCodeExamples && page.metadata.codeExamples === 0)
                continue;
            const docTitleClean = page.title.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
            const docContentClean = page.content.markdown.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
            const docKeywordsClean = page.metadata.keywords.join(' ').toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
            // Calculate score
            let score = 0;
            // 1. Exact title match
            if (docTitleClean === queryClean) {
                score += 100;
            }
            // 2. All terms in title
            if (queryTerms.length > 0 && queryTerms.every(t => docTitleClean.includes(t))) {
                score += 50;
            }
            // 3. Terms match count in title
            const termsInTitle = queryTerms.filter(t => docTitleClean.includes(t)).length;
            score += termsInTitle * 10;
            // 4. Terms match in keywords/metadata
            const termsInKeywords = queryTerms.filter(t => docKeywordsClean.includes(t)).length;
            score += termsInKeywords * 5;
            // 5. Terms match in content
            if (queryTerms.length > 0 && queryTerms.some(t => docContentClean.includes(t))) {
                const termsInContent = queryTerms.filter(t => docContentClean.includes(t)).length;
                score += termsInContent * 2;
            }
            if (score > 0) {
                results.push({ page, score });
            }
        }
        // Sort by score
        results.sort((a, b) => b.score - a.score);
        const limit = options.limit || 10;
        return results.slice(0, limit).map(r => r.page);
    }
    /**
     * Get documentation page by ID
     */
    getDocPage(pageId) {
        this.loadDocs();
        if (!this.docs)
            return null;
        return this.docs.pages.find(p => p.id === pageId) || null;
    }
    /**
     * Get documentation page by title
     */
    getDocPageByTitle(title) {
        this.loadDocs();
        if (!this.docs)
            return null;
        const titleLower = title.toLowerCase();
        return this.docs.pages.find(p => p.title.toLowerCase() === titleLower) || null;
    }
    /**
     * List pages by category
     */
    listByCategory(category) {
        this.loadDocs();
        if (!this.docs)
            return [];
        return this.docs.pages.filter(p => p.category === category);
    }
    /**
     * Get all categories
     */
    getCategories() {
        this.loadDocs();
        if (!this.docs)
            return [];
        return Object.entries(this.docs.categories).map(([name, data]) => ({
            name,
            description: data.description,
            count: data.totalPages
        }));
    }
    /**
     * Find related pages
     */
    findRelated(pageId, limit = 5) {
        this.loadDocs();
        if (!this.docs)
            return [];
        const page = this.getDocPage(pageId);
        if (!page || !page.metadata.relatedPages)
            return [];
        const related = [];
        for (const relatedRef of page.metadata.relatedPages) {
            const relatedPage = this.getDocPage(relatedRef.id);
            if (relatedPage) {
                related.push(relatedPage);
            }
            if (related.length >= limit)
                break;
        }
        return related;
    }
    /**
     * Search by keywords
     */
    searchByKeywords(keywords) {
        this.loadDocs();
        if (!this.docs)
            return [];
        const results = new Map();
        for (const keyword of keywords) {
            const keywordLower = keyword.toLowerCase();
            for (const page of this.docs.pages) {
                if (page.metadata.keywords.some(k => k.toLowerCase() === keywordLower)) {
                    const current = results.get(page.id) || 0;
                    results.set(page.id, current + 1);
                }
            }
        }
        // Sort by match count
        const sorted = Array.from(results.entries())
            .sort((a, b) => b[1] - a[1])
            .map(([pageId]) => this.getDocPage(pageId))
            .filter((p) => p !== null);
        return sorted;
    }
    /**
     * Get documentation for a specific node
     */
    getNodeDocumentation(nodeName) {
        this.loadDocs();
        if (!this.docs)
            return [];
        return this.docs.pages.filter(p => p.nodeName?.toLowerCase() === nodeName.toLowerCase());
    }
    /**
     * Get examples (tutorials/advanced-ai pages)
     */
    getExamples(query, limit = 10) {
        this.loadDocs();
        if (!this.docs)
            return [];
        let examples = this.docs.pages.filter(p => p.category === 'tutorials' ||
            p.category === 'advanced-ai' ||
            p.subcategory === 'examples');
        if (query) {
            const queryLower = query.toLowerCase();
            examples = examples.filter(p => p.title.toLowerCase().includes(queryLower) ||
                p.metadata.keywords.some(k => k.toLowerCase().includes(queryLower)) ||
                p.metadata.useCases.some(uc => uc.toLowerCase().includes(queryLower)));
        }
        return examples.slice(0, limit);
    }
    /**
     * Get statistics
     */
    getStatistics() {
        this.loadDocs();
        if (!this.docs)
            return null;
        return {
            totalPages: this.docs.totalPages,
            byCategory: this.docs.statistics.byCategory,
            withNodeNames: this.docs.statistics.withNodeNames,
            withUseCases: this.docs.statistics.withUseCases,
            withCodeExamples: this.docs.statistics.withCodeExamples
        };
    }
}
//# sourceMappingURL=docs-provider.js.map