import CryptoJS from 'crypto-js'
import { Base64 } from 'js-base64'
import AudioPlayer from './other/audio.esm.js'
import { API_KEY, API_SECRET, APPID } from './secret'

// type ISaveAudioData = 'pcm' | 'wav'
// declare class AudioPlayer {
//   constructor(processorPath?: string)
//   private toSampleRate
//   private resumePlayDuration
//   private fromSampleRate
//   private isAudioDataEnded
//   private playAudioTime?
//   private status
//   private audioContext?
//   private bufferSource?
//   private audioDatas
//   private pcmAudioDatas
//   private audioDataOffset
//   private processor
//   postMessage({ type, data, isLastData }: {
//     type: 'base64' | 'string' | 'Int16Array' | 'Float32Array'
//     data: string | Int16Array | Float32Array
//     isLastData: boolean
//   }): void
//   private onPlay?
//   private onStop?
//   private playAudio
//   reset(): void
//   start({ autoPlay, sampleRate, resumePlayDuration }?: {
//     autoPlay?: boolean
//     sampleRate?: number
//     resumePlayDuration?: number
//   }): void
//   play(): void
//   stop(): void
//   getAudioDataBlob(type: ISaveAudioData): Blob | undefined
// }

// let total_res = ''

export const ttsStatus = ref('UNDEFINED') // "UNDEFINED" "CONNECTING" "PLAY" "STOP"
export function changeTtsStatus(status: string) {
  ttsStatus.value = status
}

export const audioPlayer = new AudioPlayer('/sdk/audio')
// audioPlayer.onPlay = () => {
//   changeTtsStatus('PLAY')
// }
// audioPlayer.onStop = (audioDatas) => {
//   console.log(audioDatas)
//   ttsStatus === 'PLAY' && changeTtsStatus('STOP')
// }

function getWebSocketUrl(): string {
  const apiKey = API_KEY
  const apiSecret = API_SECRET
  let url = 'wss://tts-api.xfyun.cn/v2/tts'
  const host = location.host
  const date = new Date().toGMTString()
  const algorithm = 'hmac-sha256'
  const headers = 'host date request-line'
  const signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/tts HTTP/1.1`
  const signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret)
  const signature = CryptoJS.enc.Base64.stringify(signatureSha)
  const authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
  const authorization = btoa(authorizationOrigin)
  url = `${url}?authorization=${authorization}&date=${date}&host=${host}`
  console.log('getWebSocketUrl : ', url)
  return url
}

function encodeText(text, type) {
  if (type === 'unicode') {
    const buf = new ArrayBuffer(text.length * 4)
    const bufView = new Uint16Array(buf)
    for (let i = 0, strlen = text.length; i < strlen; i++)
      bufView[i] = text.charCodeAt(i)

    let binary = ''
    const bytes = new Uint8Array(buf)
    const len = bytes.byteLength
    for (let i = 0; i < len; i++)
      binary += String.fromCharCode(bytes[i])

    return window.btoa(binary)
  }
  else {
    return Base64.encode(text)
    // return window.btoa(text)
  }
}

export function connectTtsWS(text: string) {
  let ttsWS: any
  const url = getWebSocketUrl()
  if ('WebSocket' in window) {
    ttsWS = new WebSocket(url)
  }
  else if ('MozWebSocket' in window) {
    ttsWS = new MozWebSocket(url)
  }
  else {
    alert('浏览器不支持WebSocket')
    return
  }
  // changeTtsStatus('CONNECTING')

  ttsWS.onopen = (e: any) => {
    audioPlayer.start({
      autoPlay: true,
      sampleRate: 16000,
      resumePlayDuration: 1000,
    })
    // changeTtsStatus('PLAY')
    // const text = ''
    const params = {
      common: {
        app_id: APPID,
      },
      business: {
        aue: 'raw',
        bgs: 0,
        auf: 'audio/L16;rate=16000',
        tte: 'UTF8',
        vcn: 'xiaoyan',
      },
      data: {
        status: 2,
        text: encodeText(text, 'UTF8'),
      },
    }
    ttsWS.send(JSON.stringify(params))
  }
  ttsWS.onmessage = (e: any) => {
    const jsonData = JSON.parse(e.data)
    // console.log('jsonData : ', jsonData)
    // 合成失败
    if (jsonData.code !== 0) {
      console.error(jsonData)
      // changeTtsStatus('UNDEFINED')
      return
    }
    audioPlayer.postMessage({
      type: 'base64',
      data: jsonData.data.audio,
      isLastData: jsonData.data.status === 2,
    })
    // total_res += jsonData.data.audio
    if (jsonData.code === 0 && jsonData.data.status === 2)
      ttsWS.close()
  }
  ttsWS.onerror = (e: any) => {
    console.error(e)
  }

  ttsWS.onclose = (e: any) => {
    console.log('ttsWS close : ', e)
    // console.log('total_res : ', total_res  audioPlayer.getAudioDataBlob('wav'))
    ttsWS.onWillResultFinish && ttsWS.onWillResultFinish(audioPlayer)
  }
  return ttsWS
}
