"use strict";
/**
 * InteractiveAgent Implementation
 *
 * Handles human-computer interaction in the terminal, providing prompts,
 * confirmations, and user input handling for the MyContext CLI workflow.
 * Supports looping capabilities and iterative refinement.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InteractiveAgent = void 0;
const readline = __importStar(require("readline"));
const chalk_1 = __importDefault(require("chalk"));
class InteractiveAgent {
    constructor() {
        this.name = "InteractiveAgent";
        this.description = "Handles human-computer interaction in the terminal for prompts, confirmations, and user input";
        this.personality = "Friendly and patient terminal assistant that guides users through interactive workflows";
        this.llmProvider = "terminal"; // Uses terminal interface, not AI
        this.expertise = [
            "user-interaction",
            "terminal-ui",
            "input-validation",
            "workflow-guidance",
        ];
        this.rl = null;
        this.timeoutHandle = null;
    }
    async run(input) {
        const startTime = Date.now();
        let retries = 0;
        try {
            this.initializeReadline();
            let response = "";
            let isValid = false;
            do {
                try {
                    response = await this.handleInteraction(input);
                    isValid = this.validateInput(response, input);
                    if (!isValid && input.retryOnError !== false) {
                        retries++;
                        console.log(chalk_1.default.yellow("❌ Invalid input. Please try again."));
                    }
                }
                catch (error) {
                    if (error instanceof Error && error.message === "TIMEOUT") {
                        if (input.retryOnError !== false) {
                            retries++;
                            console.log(chalk_1.default.yellow("⏰ Timeout reached. Please respond:"));
                        }
                        else {
                            throw error;
                        }
                    }
                    else {
                        throw error;
                    }
                }
            } while (!isValid && retries < 3);
            if (!isValid) {
                throw new Error("Maximum retries exceeded for user input");
            }
            return {
                success: true,
                response,
                metadata: {
                    inputType: input.type,
                    responseTime: Date.now() - startTime,
                    retries,
                    context: input.context,
                },
            };
        }
        finally {
            this.performCleanup();
        }
    }
    initializeReadline() {
        if (!this.rl) {
            this.rl = readline.createInterface({
                input: process.stdin,
                output: process.stdout,
            });
        }
    }
    performCleanup() {
        if (this.timeoutHandle) {
            clearTimeout(this.timeoutHandle);
            this.timeoutHandle = null;
        }
        if (this.rl) {
            this.rl.close();
            this.rl = null;
        }
    }
    async handleInteraction(input) {
        return new Promise((resolve, reject) => {
            const timeout = input.timeout || 60000; // 1 minute default timeout for faster UX
            // Set up timeout
            if (timeout > 0) {
                this.timeoutHandle = setTimeout(() => {
                    reject(new Error("TIMEOUT"));
                }, timeout);
            }
            switch (input.type) {
                case "prompt":
                    this.handlePrompt(input, resolve);
                    break;
                case "confirm":
                    this.handleConfirm(input, resolve);
                    break;
                case "select":
                    this.handleSelect(input, resolve);
                    break;
                case "multiline":
                    this.handleMultiline(input, resolve);
                    break;
                default:
                    reject(new Error(`Unknown input type: ${input.type}`));
            }
        });
    }
    handlePrompt(input, resolve) {
        if (!this.rl)
            return;
        const prompt = this.formatPrompt(input.message, input.defaultValue);
        this.rl.question(prompt, (answer) => {
            const response = answer.trim() || input.defaultValue || "";
            resolve(response);
        });
    }
    handleConfirm(input, resolve) {
        if (!this.rl)
            return;
        const prompt = `${input.message} ${chalk_1.default.gray("(y/n)")}: `;
        this.rl.question(prompt, (answer) => {
            const response = answer.toLowerCase().trim();
            if (response === "y" || response === "yes") {
                resolve("yes");
            }
            else if (response === "n" || response === "no") {
                resolve("no");
            }
            else {
                // Default to no for invalid responses
                resolve("no");
            }
        });
    }
    handleSelect(input, resolve) {
        if (!this.rl)
            return;
        const options = input.options || [];
        if (options.length === 0) {
            resolve("");
            return;
        }
        console.log(chalk_1.default.cyan(input.message));
        options.forEach((option, index) => {
            console.log(chalk_1.default.gray(`  ${index + 1}. ${option}`));
        });
        const prompt = `Select an option (1-${options.length}): `;
        this.rl.question(prompt, (answer) => {
            const index = parseInt(answer.trim()) - 1;
            if (index >= 0 && index < options.length) {
                const selected = options[index];
                if (selected) {
                    resolve(selected);
                }
                else {
                    console.log(chalk_1.default.red("Invalid selection. Please try again."));
                    this.handleSelect(input, resolve);
                }
            }
            else {
                console.log(chalk_1.default.red("Invalid selection. Please try again."));
                this.handleSelect(input, resolve);
            }
        });
    }
    async handleMultiline(input, resolve) {
        if (!this.rl)
            return;
        console.log(chalk_1.default.cyan(input.message));
        console.log(chalk_1.default.gray("Enter your response (press Ctrl+D or type 'EOF' to finish):"));
        const lines = [];
        let isReading = true;
        const onLine = (line) => {
            if (line.trim().toLowerCase() === "eof") {
                isReading = false;
                this.rl?.removeListener("line", onLine);
                this.rl?.removeListener("close", onClose);
                resolve(lines.join("\n"));
                return;
            }
            lines.push(line);
        };
        const onClose = () => {
            isReading = false;
            this.rl?.removeListener("line", onLine);
            this.rl?.removeListener("close", onClose);
            resolve(lines.join("\n"));
        };
        this.rl?.on("line", onLine);
        this.rl?.on("close", onClose);
    }
    formatPrompt(message, defaultValue) {
        if (defaultValue) {
            return `${message} ${chalk_1.default.gray(`(${defaultValue})`)}: `;
        }
        return `${message}: `;
    }
    validateInput(input, config) {
        if (!config.validate)
            return true;
        const result = config.validate(input);
        if (typeof result === "boolean") {
            return result;
        }
        else {
            console.log(chalk_1.default.red(`❌ ${result}`));
            return false;
        }
    }
    validate(input) {
        // Validate that the input has required fields
        if (!input.message || !input.type) {
            return false;
        }
        if (input.type === "select" &&
            (!input.options || input.options.length === 0)) {
            return false;
        }
        return true;
    }
    async cleanup() {
        this.performCleanup();
    }
    async getStatus() {
        return {
            name: this.name,
            status: "idle",
            activeInteractions: this.rl ? 1 : 0,
            lastCleanup: new Date(),
            errorCount: 0,
            successCount: 0,
        };
    }
    // Helper methods for common interactions
    async promptUser(message, defaultValue) {
        return this.run({
            type: "prompt",
            message,
            defaultValue,
        }).then((result) => result.response);
    }
    async confirmAction(message) {
        const result = await this.run({
            type: "confirm",
            message,
        });
        return result.response === "yes";
    }
    async selectOption(message, options) {
        const result = await this.run({
            type: "select",
            message,
            options,
        });
        return result.response;
    }
    async getMultilineInput(message) {
        const result = await this.run({
            type: "multiline",
            message,
        });
        return result.response;
    }
}
exports.InteractiveAgent = InteractiveAgent;
//# sourceMappingURL=InteractiveAgent.js.map