<script setup lang='ts'>
// import lottie from 'lottie-web'
// import animationData from './robot.json'
import { Microphone } from '@element-plus/icons-vue'
import placeImg from './place.png'
import { TTSRecorder } from './sdk/chat'
import { audioPlayer, connectTtsWS } from './sdk/tts'
import { connectIatWS, iatStatus, recorder } from './sdk/iat'
import { qa_audio, qa_text } from './qa'
// const anim = ref(null)

// onMounted(() => {
//   lottie.loadAnimation({
//     container: anim.value,
//     renderer: 'svg',
//     loop: true,
//     autoplay: true,
//     animationData,
//   })
// })

const isWorking = ref(false)

const modelVersion = ref('3.1')

let bigModel = $ref(new TTSRecorder({ version: modelVersion.value }))

const videoRef = ref<HTMLVideoElement>()
const videoLoaded = ref(false)
function handleLoadedMetadata() {
  console.log('视频加载完成')
  videoLoaded.value = true
}
function startVideoPlay() {
  console.log('startVideoPlay')
  videoRef.value!.play()
}
function pauseVideoPlay() {
  console.log('pauseVideoPlay')
  videoRef.value!.pause()
  videoRef.value!.currentTime = 0
  isWorking.value = false
}

const ifDrawer = ref(false)
function openDrawer() {
  ifDrawer.value = true
}

const scrollbarRef = ref()

const chatList = ref<any[]>([])

const questionInput = ref('')

const audioEl = new Audio()
audioEl.addEventListener('ended', () => {
  pauseVideoPlay()
})

function sleep(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

async function handleSendMessage(q?: string, isInput?: boolean) {
  isWorking.value = true
  console.log('handleSendMessage', q, isInput)
  console.log('iatStatus', iatStatus.value)

  if (iatStatus.value === 'OPEN') {
    recorder.stop()
    // 录音机关闭后，需要等待一段时间，才能清空输入框
    await sleep(1000)
  }
  if (isInput) {
    console.log('清空输入框')
    questionInput.value = ''
  }
  if (!q)
    return
  const t = Date.now()
  chatList.value.push({
    left: false,
    name: '我',
    d: encodeURIComponent(q),
    t,
  })
  nextTick(() => {
    scrollbarRef.value.setScrollTop(99999999)
  })
  if (!isInput && qa_text[q]) {
    const i = chatList.value.push({
      left: true,
      name: '数字教师',
      d: '',
      t: t + 1,
    })
    startVideoPlay()

    const fullAnswer = qa_text[q].replace(/(\r\n|\n|\r)/gm, '<br />') ?? ''
    const fullAnswerList = fullAnswer.match(/.{1,3}/g) ?? []
    const answerAudio = qa_audio[q]
    if (answerAudio) {
      audioEl.src = answerAudio
      audioEl.play()
    }
    const timer = setInterval(() => {
      if (fullAnswerList.length === 0) {
        clearInterval(timer)
        // pauseVideoPlay()
        return
      }
      const item = fullAnswerList!.shift()
      chatList.value[i - 1].d += encodeURIComponent(item)
      nextTick(() => {
        scrollbarRef.value.setScrollTop(99999999)
      })
    }, 400)
    return
  }

  if (!['init', 'endPlay', 'errorTTS'].includes(bigModel.status)) {
    // chatList.value.push({
    //   left: true,
    //   name: '数字教师',
    //   d: encodeURIComponent(''),
    //   t,
    // })
    isWorking.value = false
    return
  }

  bigModel.start(q)
  const i = chatList.value.push({
    left: true,
    name: '数字教师',
    d: '思考中',
    t: t + 1,
  })
  // bigModel.onWillResultChange = (resultData) => {
  //   chatList.value[i - 1].d += encodeURIComponent(resultData)
  //   nextTick(() => {
  //     scrollbarRef.value.setScrollTop(99999999)
  //   })
  // }
  bigModel.onWillResultFinish = (resultData) => {
    chatList.value[i - 1].d = ''

    console.log('handleStartAudioTts', resultData)
    const fullAnswerList = resultData.match(/.{1,3}/g) ?? []
    const timer = setInterval(() => {
      if (fullAnswerList.length === 0) {
        clearInterval(timer)
        // pauseVideoPlay()
        return
      }
      const item = fullAnswerList!.shift()
      chatList.value[i - 1].d += encodeURIComponent(item)
      nextTick(() => {
        scrollbarRef.value.setScrollTop(99999999)
      })
    }, 400)
    startVideoPlay()
    handleStartAudioTts(resultData, i - 1)
  }
}

const optionInputs = [
  '如何培养良好的学习习惯',
  '如何锻炼英语口语的发音',
  '哪些学习的记忆方法较好',
]

// 音频播放结束
audioPlayer.onStop = () => {
  console.log('audioPlayer.onStop')
  pauseVideoPlay()
}

function handleStartAudioTts(text: string, idx: number) {
  console.log('handleStartAudioTts')

  const ttsWS = connectTtsWS(text)
  ttsWS.onWillResultFinish = (audioPlayer: any) => {
    console.log('read finsih : ', audioPlayer.getAudioDataBlob('wav'))
    chatList.value[idx].audio = URL.createObjectURL(audioPlayer.getAudioDataBlob('wav'))
  }
}
// 语音识别
function handleStartIat() {
  if (iatStatus.value === 'UNDEFINED' || iatStatus.value === 'CLOSED') {
    const iatWS = connectIatWS()
    iatWS.onWillResultStart = () => {
      questionInput.value = ''
    }
    iatWS.onWillResultChange = (resultData) => {
      console.log('onWillResultChange', resultData)
      questionInput.value = resultData
    }
    iatWS.onWillResultFinish = (resultData) => {
      console.log('onWillResultFinish', resultData)
    }
  }
  else if (iatStatus.value === 'OPEN') {
    recorder.stop()
  }
}

function handleChangeTab() {
  bigModel.ttsWS?.close()
  bigModel = new TTSRecorder({ version: modelVersion.value })
}
</script>

<template>
  <div
    class="fixed bottom-200px right-40px h-200px w-200px flex cursor-pointer items-center justify-center"
    @click="openDrawer"
  >
    <!-- <div ref="anim" /> -->
    <img :src="placeImg" alt="">
  </div>
  <el-drawer
    v-model="ifDrawer" direction="rtl" append-to-body :size="880" title="数字教师" :z-index="201"
    style="background-color: #f0f0f0;" class="no-mb"
  >
    <div class="flex">
      <div v-loading="!videoLoaded" element-loading-text="助教形象生成中..." class="h-820px w-400px">
        <video
          ref="videoRef" src="https://ossdownload.bozedu.net/static/webm/preview.webm "
          class="h-full flex items-center justify-center" loop muted @loadedmetadata="handleLoadedMetadata"
        />
      </div>
      <div class="w-440px flex flex-col justify-between rounded bg-white px-10px py-10px">
        <el-tabs v-model="modelVersion" stretch @tab-change="handleChangeTab">
          <el-tab-pane label="5.0" name="3.1" />
          <el-tab-pane label="6.0" name="3.5" />
        </el-tabs>
        <el-scrollbar ref="scrollbarRef" height="680px" class="px-14px">
          <div class="flex flex-col gap-4">
            <div class="rounded-4px bg-hex-f0f0f0 p-14px text-gray-500">
              <div class="mb-10px text-xs">
                您可以试着问我：
              </div>
              <ul class="space-y-3">
                <li
                  v-for="item in optionInputs" :key="item"
                  class="h-32px flex cursor-pointer items-center justify-between rounded-16px bg-white px-18px text-12px leading-32px text-black"
                  @click="handleSendMessage(item)"
                >
                  {{ item }}
                </li>
              </ul>
            </div>
            <info-item v-for="item in chatList" :key="item.t" :left="item.left" :name="item.name" :d="item.d" />
          </div>
        </el-scrollbar>
        <div class="flex items-start justify-between space-x-14px">
          <!-- <div
            class="h-32px w-32px flex flex-none cursor-pointer items-center justify-center rounded-16px bg-[#626aef] text-white"
          >
            <Microphone class="h-20px w-20px" />
          </div> -->
          <el-tooltip class="" effect="dark" content="一次语音识别时长不能超过60秒" placement="top-start">
            <el-button
              :icon="Microphone" circle
              :color="(iatStatus === 'UNDEFINED' || iatStatus === 'CLOSED') ? '#626aef' : '#f56c6c'"
              :disabled="isWorking" style="--color: #fff;" @click="handleStartIat"
            />
          </el-tooltip>
          <el-input
            v-model="questionInput" size="large" type="textarea" placeholder="请输入您的问题"
            :autosize="{ minRows: 1, maxRows: 4 }"
          />
          <el-button color="#626aef" :disabled="isWorking" @click="handleSendMessage(questionInput, true)">
            发送
          </el-button>
        </div>
      </div>
    </div>
  </el-drawer>
</template>

<style>
.no-mb .el-drawer__header {
  margin-bottom: 0px;
}
</style>
