import { EventEmitter } from "node:events";
import { logger } from "../logger.js";
/**
 * Manages all enabled channel adapters.
 * Routes incoming messages to the message queue and provides
 * a unified sendMessage interface for the agent.
 */
export class ChannelManager extends EventEmitter {
    adapters = new Map();
    config;
    queue;
    constructor(config, queue) {
        super();
        this.config = config;
        this.queue = queue;
    }
    /**
     * Register a channel adapter.
     */
    registerAdapter(adapter) {
        this.adapters.set(adapter.name, adapter);
        adapter.on("message", (msg) => {
            if (!this.queue.acceptMessage(msg))
                return;
            this.queue.enqueue(msg);
            this.emit("message", msg);
        });
        adapter.on("stop_request", (req) => {
            this.emit("stop_request", req);
        });
        adapter.on("sleep_request", (req) => {
            this.emit("sleep_request", req);
        });
        adapter.on("console_request", (req) => {
            this.emit("console_request", req);
        });
        adapter.on("restart_request", (req) => {
            this.emit("restart_request", req);
        });
        adapter.on("tunnel_request", (req) => {
            this.emit("tunnel_request", req);
        });
        adapter.on("help_request", (req) => {
            this.emit("help_request", req);
        });
        adapter.on("status_request", (req) => {
            this.emit("status_request", req);
        });
        adapter.on("backup_request", (req) => {
            this.emit("backup_request", req);
        });
        adapter.on("silent_mode_request", (req) => {
            this.emit("silent_mode_request", req);
        });
        adapter.on("weixin_login_request", (req) => {
            this.emit("weixin_login_request", req);
        });
        adapter.on("usage_request", (req) => {
            this.emit("usage_request", req);
        });
        adapter.on("screenshot_request", (req) => {
            this.emit("screenshot_request", req);
        });
        adapter.on("remote_desktop_request", (req) => {
            this.emit("remote_desktop_request", req);
        });
        adapter.on("realtime_request", (req) => {
            this.emit("realtime_request", req);
        });
        adapter.on("upgrade_beta_request", (req) => {
            this.emit("upgrade_beta_request", req);
        });
        adapter.on("upgrade_dev_request", (req) => {
            this.emit("upgrade_dev_request", req);
        });
        adapter.on("tasks_request", (req) => {
            this.emit("tasks_request", req);
        });
        adapter.on("subscribe_request", (req) => {
            this.emit("subscribe_request", req);
        });
        adapter.on("android_use_request", (req) => {
            this.emit("android_use_request", req);
        });
        adapter.on("refresh_request", (req) => {
            this.emit("refresh_request", req);
        });
        adapter.on("chat_monitor_request", (req) => {
            this.emit("chat_monitor_request", req);
        });
        adapter.on("billing_plan_selected", (event) => {
            this.emit("billing_plan_selected", event);
        });
        adapter.on("billing_bundle_selected", (event) => {
            this.emit("billing_bundle_selected", event);
        });
        adapter.on("set_request", (req) => {
            this.emit("set_request", req);
        });
        adapter.on("set_language_selected", (event) => {
            this.emit("set_language_selected", event);
        });
        adapter.on("set_timezone_selected", (event) => {
            this.emit("set_timezone_selected", event);
        });
        adapter.on("e2e_request", (req) => {
            this.emit("e2e_request", req);
        });
        adapter.on("error", (err) => {
            logger.err(`[Channel:${adapter.name}] Error: ${err.message}`);
        });
    }
    /**
     * Start all registered adapters.
     */
    async startAll() {
        // Dynamically import and register adapters based on config
        // Gmail is always enabled
        try {
            const { GmailAdapter } = await import("./gmail.js");
            const gmail = new GmailAdapter(this.config);
            this.registerAdapter(gmail);
        }
        catch (err) {
            logger.warn(`Failed to load Gmail adapter: ${err instanceof Error ? err.message : String(err)}`);
        }
        // Telegram
        if (this.config.channels.telegram?.enabled) {
            try {
                const { TelegramAdapter } = await import("./telegram.js");
                const telegram = new TelegramAdapter(this.config);
                this.registerAdapter(telegram);
            }
            catch (err) {
                logger.warn(`Failed to load Telegram adapter: ${err instanceof Error ? err.message : String(err)}`);
            }
        }
        // Discord
        if (this.config.channels.discord?.enabled) {
            try {
                const { DiscordAdapter } = await import("./discord.js");
                const discord = new DiscordAdapter(this.config);
                this.registerAdapter(discord);
            }
            catch (err) {
                logger.warn(`Failed to load Discord adapter: ${err instanceof Error ? err.message : String(err)}`);
            }
        }
        // Weixin (WeChat)
        if (this.config.channels.weixin?.enabled) {
            try {
                const { WeixinAdapter } = await import("./weixin.js");
                const weixin = new WeixinAdapter(this.config);
                this.registerAdapter(weixin);
            }
            catch (err) {
                logger.warn(`Failed to load Weixin adapter: ${err instanceof Error ? err.message : String(err)}`);
            }
        }
        // TUI (always available for local connections)
        try {
            const { TuiAdapter } = await import("./tui.js");
            const tui = new TuiAdapter();
            this.registerAdapter(tui);
        }
        catch (err) {
            logger.warn(`Failed to load TUI adapter: ${err instanceof Error ? err.message : String(err)}`);
        }
        // Start all registered adapters
        for (const [name, adapter] of this.adapters) {
            try {
                await adapter.start();
                logger.channel(name, "Started");
            }
            catch (err) {
                logger.err(`[Channel:${name}] Failed to start: ${err instanceof Error ? err.message : String(err)}`);
            }
        }
    }
    /**
     * Enqueue an internal/system message and emit the normal message event.
     * This lets non-channel subsystems reuse the existing idle wake / busy
     * interrupt path without pretending to be a real external adapter.
     */
    enqueueInternalMessage(msg) {
        this.queue.enqueue(msg);
        this.emit("message", msg);
    }
    /**
     * Send a message through a specific channel.
     */
    async sendMessage(channel, to, message, attachments, replyTo) {
        const adapter = this.adapters.get(channel);
        if (!adapter) {
            throw new Error(`Channel "${channel}" not found or not enabled`);
        }
        await adapter.sendMessage(to, message, attachments, replyTo);
    }
    /**
     * Send a typing indicator through a specific channel (best-effort).
     */
    async sendTypingIndicator(channel, to) {
        const adapter = this.adapters.get(channel);
        if (adapter?.sendTypingIndicator) {
            await adapter.sendTypingIndicator(to);
        }
    }
    /**
     * Get a registered adapter by name.
     */
    getAdapter(name) {
        return this.adapters.get(name);
    }
    /**
     * Get the names of all registered (started) adapters.
     */
    getEnabledChannels() {
        return Array.from(this.adapters.keys());
    }
    /**
     * Set the owner's Telegram user ID on the adapter so Telegram admin commands
     * are only accepted from the owner.
     */
    setTelegramOwnerUserId(id) {
        const adapter = this.adapters.get("telegram");
        if (adapter && "setOwnerUserId" in adapter) {
            adapter.setOwnerUserId(id);
        }
    }
    /**
     * Drop all Telegram access-control state accumulated before the owner was
     * established. Invoked once at the tail end of the onboarding flow so
     * pre-owner traffic does not bleed into normal operation.
     */
    clearTelegramPreOwnerAccessState() {
        const adapter = this.adapters.get("telegram");
        if (adapter && "clearPreOwnerAccessState" in adapter) {
            adapter.clearPreOwnerAccessState();
        }
    }
    /**
     * Send a payment prompt via the Telegram adapter.
     * Shows inline keyboard with plan choices from the backend.
     */
    async sendTelegramPaymentPrompt(chatId, payload) {
        const adapter = this.adapters.get("telegram");
        if (adapter && "sendPaymentPrompt" in adapter) {
            await adapter
                .sendPaymentPrompt(chatId, payload);
        }
    }
    /**
     * Send a Stripe Checkout link via the Telegram adapter.
     */
    async sendTelegramCheckoutLink(chatId, planName, checkoutUrl) {
        const adapter = this.adapters.get("telegram");
        if (adapter && "sendCheckoutLink" in adapter) {
            await adapter
                .sendCheckoutLink(chatId, planName, checkoutUrl);
        }
    }
    /**
     * Send a bundle amount selection prompt via the Telegram adapter.
     */
    async sendTelegramBundlePrompt(chatId, payload) {
        const adapter = this.adapters.get("telegram");
        if (adapter && "sendBundlePrompt" in adapter) {
            await adapter
                .sendBundlePrompt(chatId, payload);
        }
    }
    /**
     * Send a Telegram Mini App (Web App) button.
     */
    async sendTelegramMiniAppButton(chatId, text, buttonLabel, webAppUrl) {
        const adapter = this.adapters.get("telegram");
        if (adapter && "sendMiniAppButton" in adapter) {
            await adapter
                .sendMiniAppButton(chatId, text, buttonLabel, webAppUrl);
        }
    }
    /**
     * Send the /settings top-level settings menu via the Telegram adapter.
     */
    async sendTelegramSetMenu(chatId) {
        const adapter = this.adapters.get("telegram");
        if (adapter && "sendSetMenu" in adapter) {
            await adapter
                .sendSetMenu(chatId);
        }
    }
    /**
     * Update the Discord adapter's allowed channel IDs.
     * Called after owner onboarding completes with IDs from owner.json.
     */
    setDiscordAllowedChannelIds(ids) {
        const adapter = this.adapters.get("discord");
        if (adapter && "setAllowedChannelIds" in adapter) {
            adapter.setAllowedChannelIds(ids);
        }
    }
    /**
     * Stop all channel adapters.
     */
    async stopAll() {
        for (const [name, adapter] of this.adapters) {
            try {
                await adapter.stop();
                logger.channel(name, "Stopped");
            }
            catch (err) {
                logger.err(`[Channel:${name}] Failed to stop: ${err instanceof Error ? err.message : String(err)}`);
            }
        }
    }
}
//# sourceMappingURL=manager.js.map