import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'fs';
import { join, resolve } from 'path';
import { logger } from '../utils/logger.js';
import { summarizeError } from '../utils/error-display.js';
/**
 * BookmarkManager - Tracks bookmarked blocks and saves block content to disk.
 *
 * Bookmarks are stored in memory for the session. Saved block content is
 * written to the configured bookmarks directory.
 */
export class BookmarkManager {
    bookmarks = new Map();
    saveDir;
    constructor(baseDir) {
        this.saveDir = baseDir;
    }
    /**
     * toggle - Toggle bookmark state for a block key.
     * Returns the new state: true = bookmarked, false = removed.
     */
    toggle(key, label) {
        if (this.bookmarks.has(key)) {
            this.bookmarks.delete(key);
            return false;
        }
        else {
            this.bookmarks.set(key, {
                key,
                label: label ?? key,
                timestamp: Date.now(),
            });
            return true;
        }
    }
    /**
     * isBookmarked - Check if a block key is bookmarked.
     */
    isBookmarked(key) {
        return this.bookmarks.has(key);
    }
    /**
     * list - Return all current bookmarks sorted by timestamp.
     */
    list() {
        return Array.from(this.bookmarks.values()).sort((a, b) => a.timestamp - b.timestamp);
    }
    /**
     * clear - Remove all bookmarks.
     */
    clear() {
        this.bookmarks.clear();
    }
    /**
     * saveToFile - Write block content to a file in the bookmarks directory.
     * Returns the file path on success, or throws on failure.
     */
    saveToFile(content, label) {
        mkdirSync(this.saveDir, { recursive: true });
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
        const sanitizedLabel = label
            .toLowerCase()
            .replace(/[^a-z0-9_-]/g, '-')
            .replace(/-+/g, '-')
            .replace(/^-+|-+$/g, '')
            .slice(0, 40) || 'block';
        const filename = `${timestamp}-${sanitizedLabel}.txt`;
        const filePath = join(this.saveDir, filename);
        writeFileSync(filePath, content, 'utf-8');
        logger.debug('BookmarkManager: saved block content', { filePath });
        return filePath;
    }
    /**
     * listSavedFiles - List all previously saved block content files.
     */
    listSavedFiles() {
        if (!existsSync(this.saveDir))
            return [];
        try {
            return readdirSync(this.saveDir)
                .filter(f => f.endsWith('.txt'))
                .map(f => join(this.saveDir, f))
                .sort();
        }
        catch (err) {
            logger.warn('BookmarkManager: failed to list saved files', { dir: this.saveDir, error: summarizeError(err) });
            return [];
        }
    }
    /**
     * loadSavedFile - Read a previously saved block content file by name.
     */
    loadSavedFile(name) {
        const sanitized = name.endsWith('.txt') ? name : `${name}.txt`;
        const resolved = resolve(join(this.saveDir, sanitized));
        if (!resolved.startsWith(resolve(this.saveDir) + '/') && resolved !== resolve(this.saveDir)) {
            throw new Error('Invalid bookmark name');
        }
        const filePath = resolved;
        if (!existsSync(filePath))
            return null;
        try {
            return readFileSync(filePath, 'utf-8');
        }
        catch (err) {
            logger.warn('BookmarkManager: failed to read saved file', { filePath, error: summarizeError(err) });
            return null;
        }
    }
}
