import { isWhatsAppRemoteControlAllowed, TEAM_WHATSAPP_DISABLED_MESSAGE } from './policy.js';
export class ShortyPhoneManager {
    brokerClient;
    teamAccount;
    lastStatus = {
        enabled: false,
        pairedChatId: null
    };
    listeners = new Set();
    statusPollTimer;
    statusPollInFlight;
    constructor(options) {
        this.brokerClient = options.brokerClient;
        this.teamAccount = options.teamAccount === true;
    }
    getStatus() {
        return { ...this.lastStatus };
    }
    async refreshStatus() {
        if (!this.isWhatsAppAllowed()) {
            return this.applyWhatsAppDisabledStatus();
        }
        this.updateStatus(this.applyWhatsAppPolicy(this.normalizeStatus(await this.brokerClient.getBrokerStatus())));
        return this.getStatus();
    }
    async autoStartConfiguredProvider() {
        if (!this.isWhatsAppAllowed()) {
            return this.applyWhatsAppDisabledStatus();
        }
        this.updateStatus(this.applyWhatsAppPolicy(await this.hydrateTransientStatus(this.normalizeStatus(await this.brokerClient.autoStartConfiguredProvider()))));
        return this.getStatus();
    }
    async connectWhatsApp() {
        this.assertWhatsAppAllowed();
        this.updateStatus(this.applyWhatsAppPolicy(await this.hydrateTransientStatus(this.normalizeStatus(await this.brokerClient.connectWhatsApp()))));
        return this.getStatus();
    }
    async resetWhatsAppLink(options) {
        this.assertWhatsAppAllowed();
        this.updateStatus(this.applyWhatsAppPolicy(await this.hydrateTransientStatus(this.normalizeStatus(await this.brokerClient.resetWhatsAppLink({ reconnect: options?.reconnect === true })))));
        return this.getStatus();
    }
    async disconnect() {
        await this.brokerClient.disconnect();
        this.updateStatus(this.applyWhatsAppPolicy(this.normalizeStatus(this.brokerClient.getStatus())));
    }
    subscribe(listener) {
        this.listeners.add(listener);
        if (this.listeners.size === 1) {
            this.startPolling();
        }
        return () => {
            this.listeners.delete(listener);
            if (this.listeners.size === 0) {
                this.stopPolling();
            }
        };
    }
    async close() {
        this.stopPolling();
        await this.brokerClient.close();
    }
    async setTeamAccount(teamAccount) {
        const wasWhatsAppAllowed = this.isWhatsAppAllowed();
        this.teamAccount = teamAccount;
        const isNowWhatsAppAllowed = this.isWhatsAppAllowed();
        if (isNowWhatsAppAllowed) {
            return;
        }
        this.applyWhatsAppDisabledStatus();
        if (wasWhatsAppAllowed) {
            await this.brokerClient.disconnect();
        }
    }
    normalizeStatus(status) {
        return {
            enabled: status.enabled,
            provider: status.provider,
            pairedChatId: status.pairedChatId,
            qrText: status.qrText,
            lastError: status.lastError,
            liveDesktopCount: status.liveDesktopCount,
            currentDesktopLabel: status.currentDesktopLabel,
            activeDesktopLabel: status.activeDesktopLabel,
            currentDesktopIsActiveTarget: status.currentDesktopIsActiveTarget,
            switchableToCurrentDesktop: status.switchableToCurrentDesktop
        };
    }
    async hydrateTransientStatus(status) {
        if (!this.isWhatsAppAllowed()) {
            return this.getWhatsAppDisabledStatus();
        }
        if (!this.shouldPollForQr(status)) {
            return this.applyWhatsAppPolicy(status);
        }
        const startedAt = Date.now();
        let latest = status;
        while (Date.now() - startedAt < 5_000) {
            await new Promise((resolve) => setTimeout(resolve, 100));
            if (!this.isWhatsAppAllowed()) {
                return this.getWhatsAppDisabledStatus();
            }
            latest = this.normalizeStatus(await this.brokerClient.getBrokerStatus());
            latest = this.applyWhatsAppPolicy(latest);
            if (!this.shouldPollForQr(latest)) {
                return latest;
            }
        }
        return latest;
    }
    shouldPollForQr(status) {
        return (status.enabled === true &&
            status.provider === 'whatsapp' &&
            !status.lastError &&
            !status.pairedChatId &&
            !status.qrText);
    }
    isWhatsAppAllowed() {
        return isWhatsAppRemoteControlAllowed({ teamAccount: this.teamAccount });
    }
    assertWhatsAppAllowed() {
        if (!this.isWhatsAppAllowed()) {
            throw new Error(TEAM_WHATSAPP_DISABLED_MESSAGE);
        }
    }
    getWhatsAppDisabledStatus() {
        return {
            enabled: false,
            provider: 'whatsapp',
            pairedChatId: null,
            lastError: TEAM_WHATSAPP_DISABLED_MESSAGE
        };
    }
    applyWhatsAppPolicy(status) {
        return this.isWhatsAppAllowed() ? status : this.getWhatsAppDisabledStatus();
    }
    applyWhatsAppDisabledStatus() {
        this.updateStatus(this.getWhatsAppDisabledStatus());
        return this.getStatus();
    }
    startPolling() {
        if (this.statusPollTimer) {
            return;
        }
        this.statusPollTimer = setInterval(() => {
            void this.pollForStatusChanges();
        }, 500);
        this.statusPollTimer.unref?.();
    }
    stopPolling() {
        if (this.statusPollTimer) {
            clearInterval(this.statusPollTimer);
            this.statusPollTimer = undefined;
        }
    }
    async pollForStatusChanges() {
        if (this.statusPollInFlight || this.listeners.size === 0) {
            return;
        }
        this.statusPollInFlight = (async () => {
            try {
                if (!this.isWhatsAppAllowed()) {
                    this.applyWhatsAppDisabledStatus();
                    return;
                }
                this.updateStatus(this.applyWhatsAppPolicy(this.normalizeStatus(await this.brokerClient.getBrokerStatus())));
            }
            catch {
                // Polling is best effort. Slash commands still surface explicit failures.
            }
        })();
        try {
            await this.statusPollInFlight;
        }
        finally {
            this.statusPollInFlight = undefined;
        }
    }
    updateStatus(nextStatus) {
        if (this.statusesEqual(this.lastStatus, nextStatus)) {
            return;
        }
        const previousStatus = this.getStatus();
        this.lastStatus = { ...nextStatus };
        for (const listener of this.listeners) {
            listener(this.getStatus(), previousStatus);
        }
    }
    statusesEqual(left, right) {
        return (left.provider === right.provider &&
            left.enabled === right.enabled &&
            left.pairedChatId === right.pairedChatId &&
            left.qrText === right.qrText &&
            left.lastError === right.lastError &&
            left.liveDesktopCount === right.liveDesktopCount &&
            left.currentDesktopLabel === right.currentDesktopLabel &&
            left.activeDesktopLabel === right.activeDesktopLabel &&
            left.currentDesktopIsActiveTarget === right.currentDesktopIsActiveTarget &&
            left.switchableToCurrentDesktop === right.switchableToCurrentDesktop);
    }
}
//# sourceMappingURL=shorty-phone-manager.js.map