import WebSocket from 'ws';
import { createLogger } from './logger.js';
const xaiLogger = createLogger('XAI');
export class XaiRealtimeClient {
    ws = null;
    apiKey;
    baseUrl = 'wss://api.x.ai/v1/realtime';
    callbacks;
    isConnected = false;
    constructor(options) {
        this.apiKey = options.apiKey;
        this.callbacks = options.callbacks || {};
    }
    async connect() {
        return new Promise((resolve, reject) => {
            this.ws = new WebSocket(this.baseUrl, {
                headers: {
                    Authorization: `Bearer ${this.apiKey}`,
                },
            });
            this.ws.on('open', () => {
                xaiLogger.log('WebSocket connected');
                this.isConnected = true;
                this.callbacks.onOpen?.();
                resolve();
            });
            this.ws.on('message', (data) => {
                try {
                    const event = JSON.parse(data.toString());
                    this.callbacks.onMessage?.(event);
                }
                catch (error) {
                    xaiLogger.error('Failed to parse message:', error);
                }
            });
            this.ws.on('error', (error) => {
                xaiLogger.error('WebSocket error:', error);
                this.callbacks.onError?.(error);
                if (!this.isConnected) {
                    reject(error);
                }
            });
            this.ws.on('close', (code, reason) => {
                xaiLogger.log('WebSocket closed:', code, reason.toString());
                this.isConnected = false;
                this.callbacks.onClose?.({ code, reason: reason.toString() });
            });
        });
    }
    send(event) {
        if (!this.ws || !this.isConnected) {
            throw new Error('WebSocket is not connected');
        }
        this.ws.send(JSON.stringify(event));
    }
    updateSession(session) {
        this.send({ type: 'session.update', session });
    }
    appendInputAudio(base64Audio) {
        this.send({ type: 'input_audio_buffer.append', audio: base64Audio });
    }
    commitInputAudio() {
        this.send({ type: 'input_audio_buffer.commit' });
    }
    clearInputAudio() {
        this.send({ type: 'input_audio_buffer.clear' });
    }
    createConversationItem(item, previousItemId) {
        this.send({
            type: 'conversation.item.create',
            previous_item_id: previousItemId,
            item,
        });
    }
    sendFunctionCallOutput(callId, output) {
        this.createConversationItem({
            type: 'function_call_output',
            call_id: callId,
            output,
        });
    }
    createResponse(modalities) {
        this.send({ type: 'response.create', response: modalities ? { modalities } : undefined });
    }
    close() {
        if (this.ws) {
            this.ws.close();
            this.ws = null;
            this.isConnected = false;
        }
    }
    get connected() {
        return this.isConnected;
    }
}
