import type { AgentResponse } from './runtime';

export type OpenVTControlOptions = {
  host?: string;
  port?: number;
};

export class OpenVTControlClient {
  private readonly host: string;
  private readonly port: number;

  constructor(options: OpenVTControlOptions = {}) {
    this.host = options.host ?? '127.0.0.1';
    this.port = options.port ?? 25733;
  }

  async sendResponse(response: AgentResponse) {
    const messages: Array<Record<string, unknown>> = [];

    for (const action of response.actions) {
      if (action.type === 'talk:start') messages.push({ type: 'talk', state: 'start' });
      if (action.type === 'talk:stop') messages.push({ type: 'talk', state: 'stop' });
      if (action.type === 'emotion') messages.push({ type: 'emotion', value: action.value });
      if (action.type === 'gesture') messages.push({ type: 'gesture', value: action.value });
    }

    messages.push({ type: 'text', value: response.reply });

    for (const message of messages) {
      await this.sendMessage(message);
    }
  }

  async sendTalkState(state: 'start' | 'stop') {
    await this.sendMessage({ type: 'talk', state });
  }

  async sendEmotion(value: 'neutral' | 'happy' | 'excited' | 'curious') {
    await this.sendMessage({ type: 'emotion', value });
  }

  async sendText(value: string) {
    await this.sendMessage({ type: 'text', value });
  }

  async sendMessage(message: Record<string, unknown>) {
    const socket = await Bun.connect({
      hostname: this.host,
      port: this.port,
      socket: {
        open(socket) {
          socket.write(JSON.stringify(message));
          socket.end();
        },
        data() {},
        close() {},
        error() {},
      },
    });

    socket.unref?.();
  }
}
