import { readJson, writeJson, hashProjectPath } from './base-store.js';
import { withFileLock } from './file-mutex.js';
// ---------------------------------------------------------------------------
// Text tokenizer (Jaccard-ready) — SPEC-526
// ---------------------------------------------------------------------------
const STOP_WORDS = new Set([
    'a',
    'an',
    'the',
    'and',
    'or',
    'but',
    'in',
    'on',
    'at',
    'to',
    'for',
    'of',
    'with',
    'by',
    'from',
    'is',
    'are',
    'was',
    'were',
    'be',
    'been',
    'as',
    'that',
    'this',
    'it',
    'its',
    'we',
    'i',
    'you',
    'he',
    'she',
    'they',
]);
function tokenize(text) {
    return text
        .toLowerCase()
        .replace(/[^a-z0-9\s]/g, ' ')
        .split(/\s+/)
        .filter((w) => w.length > 2 && !STOP_WORDS.has(w));
}
function jaccardSimilarity(a, b) {
    const setA = new Set(a);
    const setB = new Set(b);
    let intersection = 0;
    for (const word of setA) {
        if (setB.has(word)) {
            intersection++;
        }
    }
    const union = setA.size + setB.size - intersection;
    return union === 0 ? 0 : intersection / union;
}
function lessonsFile(projectPath) {
    const hash = hashProjectPath(projectPath);
    return `data/projects/${hash}/lessons.json`;
}
/** Generate a unique lesson ID from an already-loaded lessons array. */
function generateLessonIdFromList(lessons) {
    const today = new Date();
    const dateStr = today.toISOString().slice(0, 10).replace(/-/g, '');
    const todayPrefix = `lesson-${dateStr}-`;
    const todayCount = lessons.filter((l) => l.id.startsWith(todayPrefix)).length;
    const seq = String(todayCount + 1).padStart(3, '0');
    return `${todayPrefix}${seq}`;
}
/** Load all lessons for a project. */
export async function loadLessons(projectPath) {
    const file = lessonsFile(projectPath);
    return readJson(file, []);
}
/** Add a new lesson to the project's lessons store. */
export async function addLesson(projectPath, data) {
    const file = lessonsFile(projectPath);
    return withFileLock(file, async () => {
        const existing = await readJson(file, []);
        const id = generateLessonIdFromList(existing);
        const lesson = {
            ...data,
            id,
            createdAt: new Date().toISOString(),
        };
        existing.push(lesson);
        await writeJson(file, existing);
        return lesson;
    });
}
// LessonFilters is defined in src/types/lessons.ts and re-exported from src/types/index.ts
/** Get lessons for a project, optionally filtered. */
export async function getLessons(projectPath, filters = {}) {
    const all = await loadLessons(projectPath);
    let result = all;
    if (filters.category !== undefined) {
        result = result.filter((l) => l.category === filters.category);
    }
    if (filters.severity !== undefined) {
        result = result.filter((l) => l.severity === filters.severity);
    }
    if (filters.specId !== undefined) {
        result = result.filter((l) => l.specId === filters.specId);
    }
    if (filters.tags !== undefined && filters.tags.length > 0) {
        result = result.filter((l) => (filters.tags ?? []).some((t) => l.tags.includes(t)));
    }
    const limit = filters.limit ?? 20;
    return result.slice(-limit);
}
/** Delete a lesson by ID. Returns true if deleted, false if not found. */
export async function deleteLesson(projectPath, id) {
    const file = lessonsFile(projectPath);
    let deleted = false;
    await withFileLock(file, async () => {
        const existing = await readJson(file, []);
        const idx = existing.findIndex((l) => l.id === id);
        if (idx === -1) {
            return;
        }
        existing.splice(idx, 1);
        await writeJson(file, existing);
        deleted = true;
    });
    return deleted;
}
const MIN_SCORE = 0.05;
const DEFAULT_SEARCH_LIMIT = 10;
/**
 * Full-text search over lessons using Jaccard similarity.
 * Tokenizes title + description + tags and scores each lesson against the query.
 * Returns top-N lessons sorted by score descending, filtered by score > MIN_SCORE.
 * SPEC-526
 */
export async function searchLessons(query, projectPath, limit = DEFAULT_SEARCH_LIMIT) {
    const all = await loadLessons(projectPath);
    if (all.length === 0) {
        return [];
    }
    const queryTokens = tokenize(query);
    if (queryTokens.length === 0) {
        return [];
    }
    const scored = [];
    for (const lesson of all) {
        const lessonText = `${lesson.title} ${lesson.description} ${lesson.tags.join(' ')}`;
        const lessonTokens = tokenize(lessonText);
        const score = jaccardSimilarity(queryTokens, lessonTokens);
        if (score > MIN_SCORE) {
            scored.push({ lesson, score });
        }
    }
    return scored.sort((a, b) => b.score - a.score).slice(0, limit);
}
//# sourceMappingURL=lessons-store.js.map