import WebSocket from 'ws';
export class RemoteControlRelayClient {
    runtime;
    options;
    socket;
    unsubscribe;
    constructor(runtime, options) {
        this.runtime = runtime;
        this.options = options;
    }
    async connect() {
        if (this.socket) {
            throw new Error('Remote control relay client already connected');
        }
        this.socket = new WebSocket(this.options.url, {
            headers: {
                Authorization: `Bearer ${this.options.accessToken}`
            }
        });
        this.unsubscribe = this.runtime.subscribe((event) => {
            this.send({
                type: 'event',
                event
            });
        });
        this.socket.on('message', (raw) => {
            void this.handleMessage(String(raw));
        });
        await new Promise((resolve, reject) => {
            this.socket.once('open', () => {
                this.send({
                    type: 'desktop_hello',
                    desktopId: this.options.desktopId,
                    label: this.options.label
                });
                resolve();
            });
            this.socket.once('error', reject);
        });
        this.socket.once('close', () => {
            this.runtime.detach();
            this.unsubscribe?.();
            this.unsubscribe = undefined;
            this.socket = undefined;
        });
    }
    async close() {
        this.runtime.detach();
        this.unsubscribe?.();
        this.unsubscribe = undefined;
        await new Promise((resolve) => {
            if (!this.socket) {
                resolve();
                return;
            }
            this.socket.once('close', () => resolve());
            this.socket.close();
        });
    }
    async handleMessage(raw) {
        let message;
        try {
            message = JSON.parse(raw);
        }
        catch {
            return;
        }
        if ('command' in message) {
            try {
                const result = await this.runtime.handleCommand(message.command);
                this.send({
                    type: 'response',
                    id: message.id,
                    result
                });
            }
            catch (error) {
                this.send({
                    type: 'error',
                    id: message.id,
                    error: error instanceof Error ? error.message : String(error)
                });
            }
            return;
        }
        if (message.type === 'controller_detached' || message.type === 'desktop_offline') {
            this.runtime.detach();
        }
    }
    send(message) {
        if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
            return;
        }
        this.socket.send(JSON.stringify(message));
    }
}
//# sourceMappingURL=relay-client.js.map