import CryptoJS from 'crypto-js'
import { API_KEY, API_SECRET, APPID } from './secret'
import { user } from '~/store/index'

let total_res = '' // 保存回答历史

// const version = '3.5'

function getWebsocketUrl(version: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const apiKey = API_KEY
    const apiSecret = API_SECRET
    let url = `wss://spark-api.xf-yun.com/v${version}/chat`
    const host = location.host
    const date = new Date().toGMTString()
    // const date = Date.now()
    const algorithm = 'hmac-sha256'
    const headers = 'host date request-line'
    const signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v${version}/chat 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}`
    // url = `${url}?authorization=${encodeURIComponent(authorization)}&date=${encodeURIComponent(date)}&host=${encodeURIComponent(host)}`
    console.log('getWebsocketUrl : ', url)
    resolve(url)
  })
}

export class TTSRecorder {
  appId: string
  status: string
  ttsWS?: WebSocket
  version = '3.1'
  playTimeout: any
  onWillStatusChange?: (oldStatus: string, newStatus: string) => void
  onWillResultChange?: (answerPart: string) => void
  onWillResultFinish?: (answerFull: string) => void

  constructor(args: { version: string }) {
    this.appId = APPID
    this.status = 'init'
    this.version = args.version
    console.log('TTSRecorder init', this.version)
  }

  // 修改状态
  setStatus(status) {
    this.onWillStatusChange && this.onWillStatusChange(this.status, status)
    this.status = status
  }

  // 连接websocket
  connectChatWS(question: string) {
    this.setStatus('ttsing')
    return getWebsocketUrl(this.version).then((url) => {
      let ttsWS
      if ('WebSocket' in window) {
        this.ttsWS = ttsWS = new WebSocket(url)
        console.log('WebSocket创建成功')
      }
      else if ('MozWebSocket' in window) {
        // @ts-expect-error MozWebSocket
        this.ttsWS = ttsWS = new MozWebSocket(url)
        console.log('WebSocket创建成功')
      }
      else {
        console.error('浏览器不支持WebSocket')
        alert('浏览器不支持WebSocket')
        return
      }
      ttsWS.onopen = (e: any) => {
        this.webSocketSend(question)
      }
      ttsWS.onmessage = (e: any) => {
        this.result(e.data)
      }
      ttsWS.onerror = (e: any) => {
        clearTimeout(this.playTimeout)
        this.setStatus('error')
        alert('WebSocket报错，请f12查看详情')
        console.error(`详情查看：${encodeURI(url.replace('wss:', 'https:'))}`)
      }
      ttsWS.onclose = (e: any) => {
        console.log(e)
      }
    })
  }

  // websocket发送数据
  webSocketSend(question: string) {
    const params = {
      header: {
        app_id: this.appId,
        uid: user.value?.user_id,
      },
      parameter: {
        chat: {
          domain: 'generalv3',
          // temperature: 0.5,
          // max_tokens: 1024,
          auditing: 'default',
        },
      },
      payload: {
        message: {
          text: [
            // {
            //   role: 'user',
            //   content: '中国第一个皇帝是谁？',
            // },
            // {
            //   role: 'assistant',
            //   content: '秦始皇',
            // },
            {
              role: 'user',
              content: question,
            },
          ],
        },
      },
    }
    console.log(params)
    console.log(JSON.stringify(params))
    this.ttsWS?.send(JSON.stringify(params))
  }

  start(question: string) {
    total_res = '' // 清空回答历史
    return this.connectChatWS(question)
  }

  // websocket接收数据的处理
  result(resultData: string) {
    const jsonData = JSON.parse(resultData)

    // console.log('websocket接收数据的处理 : ', jsonData)

    // 提问失败
    if (jsonData.header.code !== 0) {
      // alert(`提问失败: ${jsonData.header.code}:${jsonData.header.message}`)
      console.error(`${jsonData.header.code}:${jsonData.header.message}`)
      this.onWillResultChange && this.onWillResultChange(jsonData.header.message)
      return
    }

    total_res = total_res + jsonData?.payload?.choices?.text?.[0]?.content
    this.onWillResultChange && this.onWillResultChange(jsonData?.payload?.choices?.text?.[0]?.content)

    if (jsonData.header.code === 0 && jsonData.header.status === 2) {
      this.ttsWS?.close()
      this.setStatus('init')
      this.onWillResultFinish && this.onWillResultFinish(total_res)
    }

    return jsonData
  }
}
