import type { SerialTaskExecuteContext } from '../../handler'
import type { BusinessParams, SystemConfig } from '../../types'
import { createWebSocket, objectToQueryString } from '@minto-ai/tools'

import { SerialHandler } from '../../handler'

class TtsRequest extends SerialHandler<string, string> {
  private webSocketInstance: WebSocket | null = null

  private businessParams!: BusinessParams

  private systemConfig!: SystemConfig

  public initProperty(systemConfig: SystemConfig, businessParams: BusinessParams): void {
    this.businessParams = { ...businessParams }
    this.systemConfig = {
      ...systemConfig,
    }
  }

  public onActive(): void {
    this.webSocketInstance = createWebSocket(this.generateRequestUrl())
    this.webSocketInstance.addEventListener('message', (response: any) => {
      if (Object.prototype.toString.call(response.data) === '[object String]') {
        try {
          const data = JSON.parse(response.data)
          if (data.event === 'sentence_end') {
            this.taskCompletedCallback()
          }
          else if (data.event === 'sentence_result') {
            this.forwardToHandler(data.message)
          }
        }
        catch {
          this.forwardToHandler(response.data)
        }
      }
    })
    this.webSocketInstance.addEventListener('open', () => {
      this.taskCompletedCallback()
    })
  }

  public executePreCheck(): boolean {
    return this.webSocketInstance?.readyState === WebSocket.OPEN
  }

  public execute(context: SerialTaskExecuteContext<string, Blob>): void {
    if (context.isLastExecute) {
      this.taskCompletedCallback()
      return
    }

    if (this.webSocketInstance) {
      this.webSocketInstance.send(JSON.stringify(this.generateRequestParams(context.taskItem.original!)))
    }
  }

  private generateRequestParams(text: string): {
    event: 'text'
    text: string

  } {
    return {
      event: 'text',
      text,
    }
  }

  private generateRequestUrl(): string {
    return `${this.systemConfig.ttsRequestBaseUrl}?${objectToQueryString({ ...this.businessParams })}`
  }

  protected onFinish(): void {
    this.executeController?.$bus.emit('_ttsRequestFinish')
    this.webSocketInstance?.close()
    this.webSocketInstance = null
  }
}

export default TtsRequest
