"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchEngine = void 0;
const cell_store_1 = require("../walls/06-memory/stores/cell-store");
const COMMON_WORDS = new Set(['the', 'a', 'an', 'is', 'of', 'to', 'in', 'for', 'on', 'and', 'or', 'with', 'without', 'this', 'that', 'from', 'by', 'at', 'be', 'as', 'we', 'it', 'not', 'no', 'yes']);
class SearchEngine {
    store;
    index;
    constructor(cellDir) {
        this.store = new cell_store_1.CellStore(cellDir);
        this.index = this.store.read('index.json') || {
            version: 1, updated: Date.now(), entries: [],
        };
    }
    rebuild() {
        this.index.entries = [];
        let indexed = 0;
        // Index actual files (not hardcoded paths)
        const filesToIndex = [
            { file: 'personal/profile.json', tags: ['profile', 'developer', 'info'] },
            { file: 'personal/style.json', tags: ['style', 'syntax', 'code-style', 'naming', 'conventions'] },
            { file: 'blind-spots.json', tags: ['blind-spot', 'bugs', 'quality'] },
            { file: 'project_dna.json', tags: ['project', 'dna', 'architecture'] },
            { file: 'intelligence.json', tags: ['intelligence', 'analysis'] },
            { file: 'journey.json', tags: ['journey', 'timeline', 'progress'] },
            { file: 'knowledge-graph.json', tags: ['graph', 'dependencies', 'relationships'] },
        ];
        for (const entry of filesToIndex) {
            const data = this.store.readRaw(entry.file);
            if (data) {
                this.indexFile(entry.file, data, entry.tags);
                indexed++;
            }
        }
        this.index.updated = Date.now();
        this.save();
        return { indexed };
    }
    search(query, limit = 5) {
        const tokens = this.tokenize(query);
        if (tokens.length === 0)
            return [];
        const results = [];
        for (const entry of this.index.entries) {
            let score = 0;
            // Score by keyword matches
            for (const kw of entry.keywords) {
                for (const t of tokens) {
                    if (kw.includes(t) || t.includes(kw))
                        score += 3;
                    if (kw === t)
                        score += 5;
                }
            }
            // Score by tag matches
            for (const tag of entry.tags) {
                for (const t of tokens) {
                    if (tag.includes(t) || t.includes(tag))
                        score += 2;
                    if (tag === t)
                        score += 4;
                }
            }
            // Score by category match
            for (const t of tokens) {
                if (entry.category.includes(t) || t.includes(entry.category))
                    score += 1;
            }
            if (score > 0) {
                results.push({
                    file: entry.file,
                    category: entry.category,
                    score,
                    snippet: entry.summary.slice(0, 120),
                    tags: entry.tags,
                });
            }
        }
        return results.sort((a, b) => b.score - a.score).slice(0, limit);
    }
    getIndex() {
        return this.index;
    }
    indexFile(filePath, data, baseTags) {
        const text = typeof data === 'string' ? data : JSON.stringify(data);
        const keywords = this.extractKeywords(text, data);
        const category = filePath.split('/').pop()?.replace('.json', '') || 'unknown';
        this.index.entries.push({
            file: filePath,
            category,
            tags: baseTags,
            keywords: [...new Set(keywords)],
            summary: this.generateSummary(data, filePath),
            lastUpdated: Date.now(),
        });
    }
    extractKeywords(text, data) {
        const words = [];
        // Extract from JSON structure
        if (data && typeof data === 'object') {
            this.extractFromObject(data, words);
        }
        // Extract from text
        const tokens = this.tokenize(text);
        for (const t of tokens) {
            if (t.length > 1 && !COMMON_WORDS.has(t)) {
                words.push(t);
            }
        }
        return words.slice(0, 50);
    }
    extractFromObject(obj, words) {
        if (!obj || typeof obj !== 'object')
            return;
        // Style data
        if (Array.isArray(obj.syntax)) {
            for (const s of obj.syntax) {
                if (s.category)
                    words.push(s.category);
                if (s.preference)
                    words.push(s.preference);
                if (s.language)
                    words.push(s.language);
            }
        }
        // Naming data
        if (obj.camelCase)
            words.push('camelCase');
        if (obj.snakeCase)
            words.push('snake_case');
        if (obj.booleanNaming?.examples)
            words.push(...obj.booleanNaming.examples);
        // Structure data
        if (obj.avgFileSize)
            words.push('file-size', `${obj.avgFileSize}`);
        if (obj.earlyReturns?.percentage !== undefined)
            words.push('early-returns');
        if (obj.guardClauses?.percentage !== undefined)
            words.push('guard-clauses');
        // Blind spots
        if (Array.isArray(obj)) {
            for (const item of obj) {
                if (item.description)
                    words.push(...this.tokenize(item.description));
                if (item.category)
                    words.push(item.category);
                if (item.suggestion)
                    words.push(...this.tokenize(item.suggestion));
            }
        }
        // Frontend
        if (obj.framework?.name && obj.framework.name !== 'unknown')
            words.push(obj.framework.name);
        if (obj.styling?.name && obj.styling.name !== 'unknown')
            words.push(obj.styling.name);
        if (obj.stateManagement?.name && obj.stateManagement.name !== 'unknown')
            words.push(obj.stateManagement.name);
        // Backend
        if (obj.apiStyle?.name && obj.apiStyle.name !== 'unknown')
            words.push(obj.apiStyle.name);
        if (obj.database?.name && obj.database.name !== 'unknown')
            words.push(obj.database.name);
        if (obj.auth?.name && obj.auth.name !== 'unknown')
            words.push(obj.auth.name);
        if (obj.validation?.name && obj.validation.name !== 'unknown')
            words.push(obj.validation.name);
        // Productivity
        if (obj.decisions) {
            if (obj.decisions.topAccepted)
                words.push(...obj.decisions.topAccepted);
            if (obj.decisions.topRejected)
                words.push(...obj.decisions.topRejected);
        }
        if (obj.reverts?.files)
            words.push('reverts');
    }
    generateSummary(data, filePath) {
        const name = filePath.replace('.json', '').split('/').pop() || '';
        if (!data)
            return `${name} — No data`;
        try {
            if (Array.isArray(data)) {
                const descriptions = data
                    .filter((d) => d.description)
                    .map((d) => d.description)
                    .slice(0, 3);
                return `${name} (${data.length} items) — ${descriptions.join(', ')}`;
            }
            if (data.framework?.name && data.framework.name !== 'unknown') {
                return `${name} — ${data.framework.name} · ${data.stateManagement?.name || ''} · ${data.styling?.name || ''}`;
            }
            if (data.apiStyle?.name) {
                return `${name} — ${data.framework?.name || ''} · ${data.apiStyle.name} · ${data.database?.name || ''}`;
            }
            if (data.camelCase) {
                return `${name} — ${Math.round(data.camelCase.confidence * 100)}% camelCase, abbreviations: ${data.abbreviations?.total || 0}`;
            }
            if (data.avgFileSize) {
                return `${name} — avg file ${data.avgFileSize} lines, nesting ${data.nestingDepth?.average || 0}`;
            }
            if (data.speed) {
                return `${name} — ${data.speed.totalEdits} edits, ${data.decisions?.acceptRate || 0}% accept rate`;
            }
        }
        catch { }
        return `${name} — ${Object.keys(data).slice(0, 5).join(', ')}`;
    }
    tokenize(text) {
        return text
            .toLowerCase()
            .replace(/[^a-z0-9\s_-]/g, ' ')
            .split(/[\s_-]+/)
            .filter(t => t.length > 1);
    }
    save() {
        this.store.write('index.json', this.index);
    }
}
exports.SearchEngine = SearchEngine;
//# sourceMappingURL=search-engine.js.map