// import WebSocket from 'ws';
import { initWs } from '../../ws-adapter/index.ts';

export type VideoWSOptions = {
  url?: string;
  ws?: WebSocket;
  itn?: boolean;
  mode?: VideoWsMode;
  isFile?: boolean;
  onConnect?: () => void;
};
export const videoWsMode = ['2pass', 'online', 'offline'] as const;
type VideoWsMode = (typeof videoWsMode)[number];

export type VideoWsResult = {
  isFinal: boolean;
  mode: VideoWsMode;
  stamp_sents: { end: number; punc: string; start: number; text_seg: string; tsList: [][] }[];
  text: string;
  timestamp: string;
  wav_name: string;
};

export class VideoWS {
  ws: WebSocket;
  itn?: boolean;
  mode?: VideoWsMode;
  isFile?: boolean;
  onConnect?: () => void;
  constructor(options?: VideoWSOptions) {
    this.itn = options?.itn || false;
    this.mode = options?.mode || 'online';
    this.isFile = options?.isFile || false;
    this.initWs(options);
  }
  async initWs(options: VideoWSOptions) {
    if (options?.ws) {
      this.ws = options.ws;
    } else {
      this.ws = await initWs(options.url);
    }
    this.onConnect = options?.onConnect || (() => {});
    this.ws.onopen = this.onOpen.bind(this);
    this.ws.onmessage = this.onMessage.bind(this);
    this.ws.onerror = this.onError.bind(this);
    this.ws.onclose = this.onClose.bind(this);
  }

  async onOpen() {
    this.onConnect();
  }
  async start() {
    let isFileMode = this.isFile;
    const chunk_size = new Array(5, 10, 5);
    type OpenRequest = {
      chunk_size: number[];
      wav_name: string;
      is_speaking: boolean;
      chunk_interval: number;
      itn: boolean;
      mode: VideoWsMode;
      wav_format?: string;
      audio_fs?: number;
      hotwords?: string;
    };
    const request: OpenRequest = {
      chunk_size: chunk_size,
      wav_name: 'h5', //
      is_speaking: true,
      chunk_interval: 10,
      itn: this.itn,
      mode: this.mode || 'online',
    };
    console.log('request', request);
    if (isFileMode) {
      const file_ext = 'wav';
      const file_sample_rate = 16000;
      request.wav_format = file_ext;
      if (file_ext == 'wav') {
        request.wav_format = 'PCM';
        request.audio_fs = file_sample_rate;
      }
    }
    this.ws.send(JSON.stringify(request));
  }
  async stop() {
    var chunk_size = new Array(5, 10, 5);
    var request = {
      chunk_size: chunk_size,
      wav_name: 'h5',
      is_speaking: false,
      chunk_interval: 10,
      mode: this.mode,
    };
    this.ws.send(JSON.stringify(request));
  }
  async send(data: any) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(data);
    }
  }
  async onMessage(event: MessageEvent) {
    const data = event.data;
    try {
      const result = JSON.parse(data.toString());
      console.log('result', result);
    } catch (error) {
      console.log('error', error);
    }
  }
  async onError(event: Event) {
    console.log('onError', event);
  }
  async onClose(event: CloseEvent) {
    console.log('onClose', event);
  }
}
