import { existsSync } from 'node:fs';
import { rm } from 'node:fs/promises';
import { join } from 'node:path';
import { RemoteControlConfigStore } from '../config-store.js';
import { LinkedWhatsAppRemoteControl, loadWhatsAppTransportFactory, resolveDefaultWhatsAppRemoteControlPaths } from '../whatsapp-linked.js';
import { GlobalRemoteControlSettingsStore } from './global-settings.js';
const DEFAULT_STATUS = {
    enabled: false,
    pairedChatId: null,
    liveDesktopCount: 1
};
export class PhoneControlBrokerClient {
    agentDir;
    runtime;
    session;
    log;
    desktopId = `desktop-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
    configStore;
    settingsStore;
    injectedTransportFactory;
    phoneStatus = {
        ...DEFAULT_STATUS
    };
    whatsappController;
    whatsAppSessionReady = false;
    lastActivityAt = Date.now();
    pendingApprovalCount = 0;
    phoneOriginatedTurnActive = false;
    unsubscribeRuntime;
    constructor(options) {
        this.agentDir = options.agentDir;
        this.runtime = options.runtime;
        this.session = options.session;
        this.log = options.log ?? (() => { });
        this.injectedTransportFactory = options.transportFactory;
        this.configStore = new RemoteControlConfigStore(this.agentDir);
        this.settingsStore = new GlobalRemoteControlSettingsStore(this.agentDir);
        this.unsubscribeRuntime = this.runtime.subscribe((event) => {
            this.lastActivityAt = Date.now();
            if (event.type === 'approval_pending') {
                this.pendingApprovalCount += 1;
            }
            else if (event.type === 'approval_resolved') {
                this.pendingApprovalCount = Math.max(0, this.pendingApprovalCount - 1);
            }
            else if (event.type === 'session_event' && event.event.type === 'agent_end') {
                this.phoneOriginatedTurnActive = false;
            }
        });
    }
    getStatus() {
        return this.buildPhoneStatus();
    }
    async close() {
        this.unsubscribeRuntime();
        await this.closeController();
    }
    async getBrokerStatus() {
        return this.buildPhoneStatus();
    }
    async connectWhatsApp() {
        if (!this.whatsappController) {
            await this.startWhatsAppController();
        }
        await this.settingsStore.save({
            enabled: true,
            provider: 'whatsapp'
        });
        return this.buildPhoneStatus();
    }
    async autoStartConfiguredProvider() {
        const remoteControl = await this.settingsStore.load();
        if (!remoteControl.enabled || remoteControl.provider !== 'whatsapp') {
            return this.buildPhoneStatus();
        }
        try {
            const { defaultPaths, whatsappConfig } = await this.resolveWhatsAppConfig();
            const authDir = whatsappConfig.authDir || defaultPaths.authDir;
            if (!existsSync(join(authDir, 'creds.json'))) {
                this.phoneStatus = {
                    ...DEFAULT_STATUS,
                    provider: 'whatsapp'
                };
                return this.buildPhoneStatus();
            }
            await this.startWhatsAppController();
            if (this.phoneStatus.qrText) {
                await this.closeController();
                this.phoneStatus = {
                    ...DEFAULT_STATUS,
                    provider: 'whatsapp'
                };
            }
            return this.buildPhoneStatus();
        }
        catch (error) {
            const detail = error instanceof Error ? error.message : String(error);
            this.phoneStatus = {
                ...DEFAULT_STATUS,
                provider: 'whatsapp',
                lastError: detail
            };
            this.log(`WhatsApp phone control unavailable: ${detail}`);
            await this.closeController();
            return this.buildPhoneStatus();
        }
    }
    async disconnect() {
        await this.closeController();
        await this.settingsStore.save({
            enabled: false
        });
        this.phoneStatus = {
            ...DEFAULT_STATUS,
            provider: 'whatsapp'
        };
    }
    async resetWhatsAppLink(options) {
        const { defaultPaths, whatsappConfig } = await this.resolveWhatsAppConfig();
        const authDir = whatsappConfig.authDir || defaultPaths.authDir;
        const bindingFilePath = whatsappConfig.bindingFilePath || defaultPaths.bindingFilePath;
        const logFilePath = defaultPaths.logFilePath;
        await this.closeController();
        await Promise.all([
            rm(authDir, { recursive: true, force: true }),
            rm(bindingFilePath, { force: true }),
            rm(logFilePath, { force: true })
        ]);
        this.phoneStatus = {
            ...DEFAULT_STATUS,
            provider: 'whatsapp'
        };
        if (options?.reconnect) {
            return await this.connectWhatsApp();
        }
        await this.settingsStore.save({
            enabled: false
        });
        return this.buildPhoneStatus();
    }
    async handleCommand(command) {
        if (command.type === 'list_desktops') {
            return {
                kind: 'desktops',
                desktops: [this.buildDesktopSummary(true)]
            };
        }
        if (command.type === 'select_desktop') {
            if (command.desktopId !== this.desktopId) {
                return {
                    kind: 'desktop_missing',
                    desktopId: command.desktopId
                };
            }
            return {
                kind: 'desktop_selected',
                desktop: this.buildDesktopSummary(true)
            };
        }
        if (command.type === 'prompt' || command.type === 'follow_up' || command.type === 'steer') {
            this.phoneOriginatedTurnActive = true;
            this.lastActivityAt = Date.now();
        }
        else if (command.type === 'abort') {
            this.phoneOriginatedTurnActive = false;
        }
        return await this.runtime.handleCommand(command);
    }
    subscribe(listener) {
        return this.runtime.subscribe(listener);
    }
    buildDesktopSummary(isActiveTarget) {
        return {
            desktopId: this.desktopId,
            pid: process.pid,
            cwd: process.cwd(),
            sessionId: this.session.sessionId,
            sessionName: this.session.sessionName,
            lastActivityAt: this.lastActivityAt,
            isStreaming: this.session.isStreaming,
            pendingApprovalCount: this.pendingApprovalCount,
            phoneOriginatedTurnActive: this.phoneOriginatedTurnActive,
            isActiveTarget
        };
    }
    buildCurrentDesktopLabel() {
        const sessionName = this.session.sessionName?.trim();
        if (sessionName) {
            return sessionName;
        }
        return this.session.sessionId || process.cwd();
    }
    buildPhoneStatus() {
        return {
            ...this.phoneStatus,
            liveDesktopCount: 1,
            currentDesktopId: this.desktopId,
            currentDesktopLabel: this.buildCurrentDesktopLabel(),
            activeDesktopId: this.phoneStatus.enabled ? this.desktopId : null,
            activeDesktopLabel: this.phoneStatus.enabled ? this.buildCurrentDesktopLabel() : null,
            currentDesktopIsActiveTarget: this.phoneStatus.enabled,
            switchableToCurrentDesktop: false
        };
    }
    async resolveWhatsAppConfig() {
        const defaultPaths = resolveDefaultWhatsAppRemoteControlPaths(this.agentDir);
        const config = await this.configStore.load();
        const whatsappConfig = config.whatsapp ?? {};
        const transportFactory = this.injectedTransportFactory ??
            (whatsappConfig.transportFactoryModulePath
                ? await loadWhatsAppTransportFactory(whatsappConfig.transportFactoryModulePath)
                : undefined);
        return {
            defaultPaths,
            whatsappConfig,
            transportFactory
        };
    }
    async startWhatsAppController() {
        if (this.whatsappController) {
            return;
        }
        const { defaultPaths, whatsappConfig, transportFactory } = await this.resolveWhatsAppConfig();
        const controller = new LinkedWhatsAppRemoteControl({
            authDir: whatsappConfig.authDir || defaultPaths.authDir,
            configFilePath: this.configStore.filePath,
            bindingFilePath: whatsappConfig.bindingFilePath || defaultPaths.bindingFilePath,
            logFilePath: defaultPaths.logFilePath,
            runtime: this,
            transportFactory,
            log: this.log,
            onStateChange: (event) => {
                this.handleWhatsAppStateChange(event);
            }
        });
        this.whatsappController = controller;
        this.whatsAppSessionReady = false;
        try {
            const startStatus = await controller.start();
            const qrText = startStatus.qrText ??
                (!startStatus.pairedChatId ? await this.waitForWhatsAppQrOrReady(controller) : undefined);
            this.phoneStatus = {
                enabled: true,
                provider: 'whatsapp',
                pairedChatId: this.phoneStatus.pairedChatId ?? startStatus.pairedChatId,
                qrText,
                lastError: undefined,
                liveDesktopCount: 1
            };
        }
        catch (error) {
            this.whatsappController = undefined;
            this.whatsAppSessionReady = false;
            throw error;
        }
    }
    async closeController() {
        if (!this.whatsappController) {
            return;
        }
        await this.whatsappController.close();
        this.whatsappController = undefined;
        this.whatsAppSessionReady = false;
    }
    handleWhatsAppStateChange(event) {
        switch (event.type) {
            case 'qr_rendered':
                this.phoneStatus = {
                    ...this.phoneStatus,
                    enabled: true,
                    provider: 'whatsapp',
                    qrText: event.qrText
                };
                return;
            case 'paired_chat_updated':
                this.phoneStatus = {
                    ...this.phoneStatus,
                    pairedChatId: event.chatId
                };
                return;
            case 'healthy':
                this.whatsAppSessionReady = true;
                this.phoneStatus = {
                    ...this.phoneStatus,
                    enabled: true,
                    provider: 'whatsapp',
                    qrText: undefined,
                    lastError: undefined
                };
                return;
            case 'issue':
                this.phoneStatus = {
                    ...this.phoneStatus,
                    lastError: event.message
                };
                return;
        }
    }
    async waitForWhatsAppQrOrReady(controller, timeoutMs = 5_000) {
        const startedAt = Date.now();
        while (Date.now() - startedAt < timeoutMs) {
            const qrText = controller.getLastQrText();
            if (qrText && qrText.trim().length > 0) {
                return qrText;
            }
            if (this.phoneStatus.pairedChatId) {
                return controller.getLastQrText();
            }
            if (this.whatsAppSessionReady) {
                return controller.getLastQrText();
            }
            await new Promise((resolve) => setTimeout(resolve, 50));
        }
        return controller.getLastQrText();
    }
}
//# sourceMappingURL=client.js.map