import { mkdir, readdir, writeFile, rm } from "fs/promises";
import { join } from "path";
import { getProjectRoot, pathExists, readTextFile } from "./fs.js";
const SNIPPETS_DIR = ".omk/snippets";
function getSnippetsPath() {
    return join(getProjectRoot(), SNIPPETS_DIR);
}
function sanitizeName(name) {
    return name.replace(/[^a-zA-Z0-9_-]/g, "_").substring(0, 128);
}
function parseSnippetFile(content, name) {
    const lines = content.split("\n");
    const meta = {};
    let bodyStart = 0;
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        if (line.startsWith("<!-- ") && line.endsWith(" -->")) {
            const inner = line.slice(5, -4).trim();
            const eq = inner.indexOf("=");
            if (eq > 0) {
                meta[inner.slice(0, eq).trim()] = inner.slice(eq + 1).trim();
            }
            bodyStart = i + 1;
        }
        else if (line.trim() === "---") {
            bodyStart = i + 1;
            break;
        }
        else if (line.trim() !== "" && !line.startsWith("<!--")) {
            break;
        }
        else {
            bodyStart = i + 1;
        }
    }
    const body = lines.slice(bodyStart).join("\n").trim();
    const now = new Date().toISOString();
    return {
        name,
        content: body,
        tags: meta.tags ? meta.tags.split(",").map((t) => t.trim()).filter(Boolean) : [],
        createdAt: meta.createdAt || now,
        updatedAt: meta.updatedAt || now,
    };
}
function serializeSnippet(snippet) {
    const tagsLine = snippet.tags.length > 0 ? `<!-- tags=${snippet.tags.join(",")} -->` : "";
    const createdLine = `<!-- createdAt=${snippet.createdAt} -->`;
    const updatedLine = `<!-- updatedAt=${snippet.updatedAt} -->`;
    return [tagsLine, createdLine, updatedLine, "", snippet.content].filter((l) => l !== undefined).join("\n");
}
export async function saveSnippet(name, content, tags) {
    const safeName = sanitizeName(name);
    const dir = getSnippetsPath();
    await mkdir(dir, { recursive: true });
    const filePath = join(dir, `${safeName}.md`);
    const now = new Date().toISOString();
    const snippet = {
        name: safeName,
        content,
        tags: tags ?? [],
        createdAt: now,
        updatedAt: now,
    };
    await writeFile(filePath, serializeSnippet(snippet), "utf-8");
    return { success: true, path: filePath };
}
export async function getSnippet(name) {
    const safeName = sanitizeName(name);
    const filePath = join(getSnippetsPath(), `${safeName}.md`);
    if (!(await pathExists(filePath)))
        return null;
    const content = await readTextFile(filePath, "");
    if (!content.trim())
        return null;
    return parseSnippetFile(content, safeName);
}
export async function deleteSnippet(name) {
    const safeName = sanitizeName(name);
    const filePath = join(getSnippetsPath(), `${safeName}.md`);
    if (!(await pathExists(filePath)))
        return { success: false };
    await rm(filePath);
    return { success: true };
}
export async function searchSnippets(query, limit = 20) {
    const dir = getSnippetsPath();
    if (!(await pathExists(dir)))
        return [];
    const entries = await readdir(dir, { withFileTypes: true });
    const results = [];
    const lowerQuery = query.toLowerCase();
    for (const entry of entries) {
        if (!entry.isFile() || !entry.name.endsWith(".md"))
            continue;
        const name = entry.name.slice(0, -3);
        const content = await readTextFile(join(dir, entry.name), "");
        if (!content.trim())
            continue;
        const snippet = parseSnippetFile(content, name);
        const text = `${snippet.name} ${snippet.content} ${snippet.tags.join(" ")}`.toLowerCase();
        if (!lowerQuery || text.includes(lowerQuery)) {
            results.push(snippet);
        }
    }
    return results.slice(0, limit);
}
export async function listSnippets() {
    return searchSnippets("", 1000);
}
