import readline from "node:readline";
import path from "node:path";
import { ExecutionLogger } from "../logging/logger.js";
export class TUI {
    agent;
    rl;
    constructor(agent) {
        this.agent = agent;
        this.rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
        });
    }
    start() {
        console.log(`\nHi, I'm ${this.agent.getName()}. Type /help for commands.\n`);
        this.prompt();
    }
    prompt() {
        this.rl.question("you> ", async (input) => {
            const trimmed = input.trim();
            if (!trimmed) {
                this.prompt();
                return;
            }
            if (trimmed.startsWith("/")) {
                await this.handleCommand(trimmed);
            }
            else {
                await this.handleChat(trimmed);
            }
            this.prompt();
        });
    }
    async handleChat(message) {
        try {
            process.stdout.write("agent> ");
            for await (const chunk of this.agent.chatStream(message)) {
                process.stdout.write(chunk);
            }
            console.log(); // newline after streaming ends
        }
        catch (err) {
            console.error("\nError:", err instanceof Error ? err.message : String(err));
        }
    }
    async handleCommand(input) {
        const parts = input.slice(1).split(/\s+/);
        const cmd = parts[0].toLowerCase();
        const args = parts.slice(1);
        try {
            switch (cmd) {
                case "tasks":
                    console.log(this.agent.listTasks());
                    break;
                case "add":
                    await this.handleAddTask();
                    break;
                case "remove":
                    if (!args[0]) {
                        console.log("Usage: /remove <task-id>");
                        break;
                    }
                    console.log(this.agent.removeTask(args[0]));
                    break;
                case "enable":
                    if (!args[0]) {
                        console.log("Usage: /enable <task-id>");
                        break;
                    }
                    console.log(this.agent.toggleTask(args[0], true));
                    break;
                case "disable":
                    if (!args[0]) {
                        console.log("Usage: /disable <task-id>");
                        break;
                    }
                    console.log(this.agent.toggleTask(args[0], false));
                    break;
                case "run":
                    if (!args[0]) {
                        console.log("Usage: /run <task-id>");
                        break;
                    }
                    console.log("Running task...");
                    const result = await this.agent.runTaskById(args[0]);
                    console.log(result);
                    break;
                case "logs": {
                    const logsDir = path.join(this.agent.getWorkspace(), "logs");
                    const logs = ExecutionLogger.listLogs(logsDir);
                    if (logs.length === 0) {
                        console.log("(no logs found)");
                    }
                    else {
                        if (args[0]) {
                            // Show specific log
                            const logFile = logs.find((l) => l.includes(args[0]));
                            if (logFile) {
                                const entries = ExecutionLogger.readLog(path.join(logsDir, logFile));
                                for (const entry of entries) {
                                    const status = entry.success ? "✓" : "✗";
                                    console.log(`  ${status} Step ${entry.step}: ${entry.action} ${JSON.stringify(Object.fromEntries(Object.entries(entry).filter(([k]) => !["step", "action", "timestamp", "success"].includes(k))))}`);
                                }
                            }
                            else {
                                console.log(`Log not found: ${args[0]}`);
                            }
                        }
                        else {
                            console.log("Recent logs:");
                            for (const log of logs.slice(0, 20)) {
                                console.log(`  ${log}`);
                            }
                        }
                    }
                    break;
                }
                case "skills":
                    console.log(this.agent.listSkills());
                    break;
                case "genskill":
                    if (!args[0]) {
                        console.log("Usage: /genskill <log-filename>");
                        break;
                    }
                    console.log("Generating skill from log...");
                    const skillResult = await this.agent.generateSkill(args[0]);
                    console.log(skillResult);
                    break;
                case "memory":
                    console.log(this.agent.listMemories());
                    break;
                case "help":
                    console.log("Commands:");
                    console.log("  /tasks          - List scheduled tasks");
                    console.log("  /add            - Add a task (interactive)");
                    console.log("  /remove <id>    - Remove a task");
                    console.log("  /enable <id>    - Enable a task");
                    console.log("  /disable <id>   - Disable a task");
                    console.log("  /run <id>       - Run a task now");
                    console.log("  /logs [id]      - View execution logs");
                    console.log("  /skills         - List available skills");
                    console.log("  /genskill <log> - Generate skill from log");
                    console.log("  /memory         - View saved memories");
                    console.log("  /quit           - Exit");
                    break;
                case "quit":
                case "exit":
                    console.log("Shutting down...");
                    await this.agent.stop();
                    process.exit(0);
                    break;
                default:
                    console.log(`Unknown command: /${cmd}. Type /help for available commands.`);
            }
        }
        catch (err) {
            console.error("Error:", err instanceof Error ? err.message : String(err));
        }
    }
    async handleAddTask() {
        const ask = (question) => new Promise((resolve) => this.rl.question(question, resolve));
        const name = await ask("Task name: ");
        const cronExpr = await ask("Cron expression (e.g., '0 9 * * *'): ");
        const prompt = await ask("Task description/prompt: ");
        const timezone = await ask("Timezone (optional, e.g. 'UTC' or 'Asia/Shanghai'): ");
        if (!name || !cronExpr || !prompt) {
            console.log("Cancelled: all fields are required.");
            return;
        }
        console.log(this.agent.addTask(name, cronExpr, prompt, timezone.trim() || undefined));
    }
    stop() {
        this.rl.close();
    }
}
//# sourceMappingURL=tui.js.map