import { readJson, writeJson, projectDataDir } from './base-store.js';
import { mkdir, cp, rm, readdir, stat } from 'node:fs/promises';
import { join } from 'node:path';
function trashDir(projectId) {
    return `${projectDataDir(projectId)}/.trash`;
}
function trashManifest(projectId) {
    return `${trashDir(projectId)}/manifest.json`;
}
/**
 * Ensure the .trash directory exists for a project.
 */
async function ensureTrashDir(projectId) {
    await mkdir(trashDir(projectId), { recursive: true });
}
/**
 * Load the trash manifest (list of all trashed items).
 */
export async function loadManifest(projectId) {
    return readJson(trashManifest(projectId), []);
}
/**
 * Save the trash manifest.
 */
async function saveManifest(projectId, items) {
    await writeJson(trashManifest(projectId), items);
}
/**
 * Move a directory to trash. Returns the TrashItem metadata.
 */
export async function moveToTrash(projectId, itemType, itemId, sourcePath, metadata) {
    await ensureTrashDir(projectId);
    const timestamp = Date.now();
    const trashSubdir = `${timestamp}-${itemType}-${itemId}`;
    const destPath = join(trashDir(projectId), trashSubdir);
    await cp(sourcePath, destPath, { recursive: true });
    await rm(sourcePath, { recursive: true, force: true });
    const item = {
        id: trashSubdir,
        itemType,
        originalPath: sourcePath,
        trashPath: destPath,
        deletedAt: new Date().toISOString(),
        metadata,
    };
    const manifest = await loadManifest(projectId);
    manifest.push(item);
    await saveManifest(projectId, manifest);
    return item;
}
/**
 * Move JSON data to trash (for patterns/decisions stored in JSON arrays).
 * Creates a JSON file in the trash directory with the item data.
 */
export async function moveDataToTrash(projectId, itemType, itemId, data, metadata) {
    await ensureTrashDir(projectId);
    const timestamp = Date.now();
    const trashSubdir = `${timestamp}-${itemType}-${itemId}`;
    const destPath = join(trashDir(projectId), trashSubdir);
    await mkdir(destPath, { recursive: true });
    await writeJson(join(destPath, 'data.json'), data);
    const item = {
        id: trashSubdir,
        itemType,
        originalPath: `${itemType}:${itemId}`,
        trashPath: destPath,
        deletedAt: new Date().toISOString(),
        metadata,
    };
    const manifest = await loadManifest(projectId);
    manifest.push(item);
    await saveManifest(projectId, manifest);
    return item;
}
/**
 * Restore an item from trash to its original location.
 */
export async function restoreFromTrash(projectId, trashItemId) {
    const manifest = await loadManifest(projectId);
    const idx = manifest.findIndex((i) => i.id === trashItemId);
    if (idx === -1) {
        return null;
    }
    const item = manifest[idx];
    /* v8 ignore next 3 -- unreachable: findIndex already validated idx */
    if (!item) {
        return null;
    }
    // Restore directory-based items
    if (!item.originalPath.includes(':')) {
        await mkdir(item.originalPath, { recursive: true });
        await cp(item.trashPath, item.originalPath, { recursive: true });
    }
    await rm(item.trashPath, { recursive: true, force: true });
    manifest.splice(idx, 1);
    await saveManifest(projectId, manifest);
    return item;
}
/**
 * Permanently remove a specific item from trash.
 */
export async function purgeTrashItem(projectId, trashItemId) {
    const manifest = await loadManifest(projectId);
    const idx = manifest.findIndex((i) => i.id === trashItemId);
    if (idx === -1) {
        return false;
    }
    const item = manifest[idx];
    /* v8 ignore next 3 -- unreachable: findIndex already validated idx */
    if (!item) {
        return false;
    }
    await rm(item.trashPath, { recursive: true, force: true });
    manifest.splice(idx, 1);
    await saveManifest(projectId, manifest);
    return true;
}
/**
 * Purge all items from trash.
 */
export async function purgeAllTrash(projectId) {
    const manifest = await loadManifest(projectId);
    const count = manifest.length;
    for (const item of manifest) {
        await rm(item.trashPath, { recursive: true, force: true });
    }
    await saveManifest(projectId, []);
    return count;
}
/**
 * Count files in a directory recursively (for project delete summary).
 */
export async function countFiles(dirPath) {
    try {
        const entries = await readdir(dirPath, { withFileTypes: true });
        let count = 0;
        for (const entry of entries) {
            if (entry.isDirectory()) {
                count += await countFiles(join(dirPath, entry.name));
            }
            else {
                count += 1;
            }
        }
        return count;
    }
    catch {
        return 0;
    }
}
/**
 * Check if a path exists.
 */
export async function pathExists(p) {
    try {
        await stat(p);
        return true;
    }
    catch {
        return false;
    }
}
//# sourceMappingURL=trash-store.js.map