import fs from "fs";
import { PROMPT_HISTORY_FILE, DATA_DIRECTORY } from "./constants.js";
import { logger } from "./globalLogger.js";
/**
 * Ensure data directory exists
 */
const ensureDataDirectory = () => {
    try {
        if (!fs.existsSync(DATA_DIRECTORY)) {
            fs.mkdirSync(DATA_DIRECTORY, { recursive: true });
        }
    }
    catch (error) {
        logger.debug("Failed to create data directory:", error);
    }
};
const MAX_HISTORY_ENTRIES = 1000;
export class PromptHistoryManager {
    /**
     * Add a new prompt to history
     */
    static async addEntry(prompt, sessionId, longTextMap, workdir) {
        try {
            if (!prompt.trim())
                return;
            ensureDataDirectory();
            const entry = {
                prompt,
                timestamp: Date.now(),
                sessionId,
                longTextMap,
                workdir,
            };
            const line = JSON.stringify(entry) + "\n";
            await fs.promises.appendFile(PROMPT_HISTORY_FILE, line, "utf-8");
            // Periodically trim history file to prevent it from growing too large
            // We do this randomly (1 in 50 chance) to avoid performance hit on every entry
            if (Math.random() < 0.02) {
                await this.trimHistory();
            }
        }
        catch (error) {
            logger.debug("Failed to add prompt to history:", error);
        }
    }
    /**
     * Trim history file to MAX_HISTORY_ENTRIES
     */
    static async trimHistory() {
        try {
            if (!fs.existsSync(PROMPT_HISTORY_FILE))
                return;
            const data = await fs.promises.readFile(PROMPT_HISTORY_FILE, "utf-8");
            const lines = data.split("\n").filter((line) => line.trim());
            if (lines.length > MAX_HISTORY_ENTRIES * 1.2) {
                const trimmedLines = lines.slice(-MAX_HISTORY_ENTRIES);
                await fs.promises.writeFile(PROMPT_HISTORY_FILE, trimmedLines.join("\n") + "\n", "utf-8");
            }
        }
        catch (error) {
            logger.debug("Failed to trim prompt history:", error);
        }
    }
    /**
     * Get all history entries
     */
    static async getHistory(options) {
        try {
            if (!fs.existsSync(PROMPT_HISTORY_FILE)) {
                return [];
            }
            const data = await fs.promises.readFile(PROMPT_HISTORY_FILE, "utf-8");
            const lines = data.split("\n").filter((line) => line.trim());
            const entries = lines
                .map((line) => {
                try {
                    return JSON.parse(line);
                }
                catch {
                    logger.debug("Failed to parse history line:", line);
                    return null;
                }
            })
                .filter((entry) => entry !== null);
            // Filter by sessionId if provided
            let filteredEntries = entries;
            if (options?.sessionId) {
                const sessionIds = Array.isArray(options.sessionId)
                    ? options.sessionId
                    : [options.sessionId];
                filteredEntries = filteredEntries.filter((entry) => entry.sessionId && sessionIds.includes(entry.sessionId));
            }
            // Filter by workdir if provided
            if (options?.workdir) {
                filteredEntries = filteredEntries.filter((entry) => entry.workdir === options.workdir);
            }
            // Deduplicate by prompt, keeping the most recent one
            const uniqueEntries = [];
            const seenPrompts = new Set();
            // Process from newest to oldest
            for (let i = filteredEntries.length - 1; i >= 0; i--) {
                const entry = filteredEntries[i];
                if (!seenPrompts.has(entry.prompt)) {
                    uniqueEntries.push(entry);
                    seenPrompts.add(entry.prompt);
                }
            }
            return uniqueEntries;
        }
        catch (error) {
            logger.debug("Failed to load prompt history:", error);
            return [];
        }
    }
    /**
     * Search history by query
     */
    static async searchHistory(query, options) {
        try {
            const history = await this.getHistory(options);
            if (!query.trim()) {
                return history;
            }
            const normalizedQuery = query.toLowerCase();
            return history.filter((entry) => entry.prompt.toLowerCase().includes(normalizedQuery));
        }
        catch (error) {
            logger.debug("Failed to search prompt history:", error);
            return [];
        }
    }
}
