<template>
  <div class="levitatedSphere" v-show="show">
    <div :class="['ls_hello']" v-show="showIndex == 0" @click="stopOne()" @dblclick="stopTwo()">
      <el-image
        style="width: 110%; height: 110%"
        v-show="aiStatus == 1"
        :src="require('../../../assets/icon/course/aiTalk.svg')"
        fit="fill"
      ></el-image>
      <el-image
        style="width: 110%; height: 110%"
        v-show="aiStatus == 2"
        :src="require('../../../assets/icon/course/aiVanish.svg')"
        fit="fill"
      ></el-image>
      <el-image
        style="width: 110%; height: 110%;transform: scale(1.3,1.3);"
        v-show="aiStatus == 0"
        :src="require('../../../assets/icon/course/aiWait2.svg')"
        fit="fill"
      ></el-image>
    </div>
    <div
      class="ls_text"
      :style="{
        width: userText || aiText || showTextIndex == 2 ? '300px' : '0px'
      }"
    >
      <div class="ls_t_ai" v-if="[0, 2].includes(showTextIndex)">
        <span
          v-if="[0].includes(showTextIndex)"
          v-html="htmlContent(aiText)"
        ></span>
        <span v-if="[2].includes(showTextIndex)">正在组织语言...</span>
      </div>
      <div class="ls_t_user" v-if="[1].includes(showTextIndex)">
        {{ userText }}
      </div>
    </div>
    <!-- 录音转文字 -->
    <iframe
      allow="camera *; microphone *;display-capture;midi;encrypted-media;"
      src="https://beta.cloud.cocorobo.cn/browser/public/index.html"
      ref="iiframe"
      v-show="false"
    ></iframe>

    <!-- 文字转语音-->
    <iframe
      allow="camera *; microphone *;display-capture;midi;encrypted-media;"
      src="https://beta.cloud.cocorobo.cn/browser/public/index1.html"
      ref="iiframe2"
      v-show="false"
    ></iframe>

		<mini-audio
      v-show="false"
      ref="audioRef"
      :loop="false"
      :audio-source="wozaiAudioUrl"
    ></mini-audio>
  </div>
</template>

<script>
import { v4 as uuidv4 } from "uuid";
import MarkdownIt from "markdown-it";
import { fetchEventSource } from "@microsoft/fetch-event-source";

export default {
  data() {
    return {
      show: false,
      showIndex: 0,
      aiStatus: 0, //0 :在说话 1 ： 接收 2：待命
      aiText: "您好，我是小可，有什么可以帮助您的？",
      userText: "",
      showTextIndex: 0, //0：ai,1：用户, 2：组织语言  3: 无
      timer: null,
      isOpen: false,
      userId: this.$route.query.userid,
      chatLoading: false,
      talkLoading: false,
      source: null,
      talkTextList: [],
			wozaiAudioUrl:"https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/default%2F%E4%B8%AD%E6%96%87%E7%89%88%E6%88%91%E5%9C%A81728961654002.wav",
			wozaiAudioEnglishUrl:"https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/default%2F%E8%8B%B1%E6%96%87%E7%89%88what%27sup1728961667376.wav",
    };
  },
  computed: {
    htmlContent() {
      const md = new MarkdownIt();
      return _md => {
        return md.render(_md);
      };
    }
  },
  methods: {
		stopTwo(){
      this.show = false;
      this.showTextIndex = 3;
      this.aiStatus = 2;
      this.aiText = "";
      this.userText = "";
      this.stopRecord();
      if(this.curRequestController){
          this.curRequestController.abort();
          console.log("请求已终止");
          this.curRequestController = null;
      }
		},
		stopOne(){
			if(this.source){
				this.source.close();
				this.source = null;
			}
			if (this.talkLoading) {
        this.stopTalk();
      }
      if(this.curRequestController){
          this.curRequestController.abort();
          console.log("请求已终止");
          this.curRequestController = null;
      }
			this.showIndex = 0;
			this.showTextIndex = 0;
			this.aiText = "您好，我是小可，有什么可以帮助您的？";
			this.aiStatus = 0;
			this.chatLoading = false;

		},
    recordStart(_text) {
      var OpenCC = require("opencc-js");
      let converter = OpenCC.Converter({
        from: "hk",
        to: "cn"
      });
      // try {
      // this.$parent.changeRecordType(1);
      // return this.$message.success("已开启语音助手，请说“可可同学”来唤醒")
      if (this.isOpen)
        return this.$message.info("已开启语音助手，无需重复开启");
      let iiframe = this.$refs["iiframe"];
      iiframe.contentWindow.window.document.getElementById(
       "languageOptions"
      ).selectedIndex = 2; //普通话
      iiframe.contentWindow.testdoContinuousPronunciationAssessment();
			//this.talkTextList.push("我在");
			//this.talkText();
			// console.log("打开")
			this.$refs.audioRef.play();
			// return;
      // this.$message.success("已开启语音助手，请说“可可同学”来唤醒");
      this.$parent.changeRecordType(1);
      this.isOpen = true;
      this.aiText = "您好，我是小可，有什么可以帮助您的？";
      this.aiStatus = 0;
      this.showIndex = 0;
			this.showTextIndex = 0;
			this.chatLoading = false;
			this.talkLoading == false;
      this.show = true;
      iiframe.contentWindow.onRecognizedResult = e => {
        let _msg = converter(e.privText);
        // let _msg2 = e.privText;
        // let _msg = "你好呀！";
        console.log("👇");
        console.log(_msg);
        // _msg = converter(_msg)
        if (!_msg || _msg == '.') return console.log("输出为空");
        // if (_msg.indexOf(converter("可可同学")) != -1 && !this.show) {
        //   this.aiText = "您好，我是小可，有什么可以帮助您的？";
        //   this.aiStatus = 0;
        //   this.showIndex = 0;
        //   this.show = true;
        //   console.log("已唤醒");
        //   return;
        // } else

        if (this.show == true) {
          if (
            _msg.indexOf(converter("可可同学")) != -1 &&
            _msg.indexOf(converter("停止")) != -1
          ) {
            this.stopTalk();
          } else if (
            this.showTextIndex == 2 ||
            this.chatLoading ||
            this.talkLoading
          ) {
            return console.log("组织语言中");
            // }else if(_msg.indexOf('可可同学')!=-1 && _msg.indexOf("停止")!=-1){
            // 	this.stopTalk();
          } else {
            this.showTextIndex = 1;
            this.aiText = "";
            this.userText += _msg;
            this.aiStatus = 1;
            if (this.timer) {
              clearTimeout(this.timer);
              this.timer = null;
            }
            this.timer = setTimeout(() => {
              if (this.userText.indexOf(converter("关闭语音助手")) != -1) {
                // return setTimeout(()=>{
                this.show = false;
                this.showTextIndex = 3;
                this.aiStatus = 2;
                this.aiText = "";
                this.userText = "";
                this.stopRecord();
                return;
                // },1000)
              }
              this.showTextIndex = 2;
              this.aiText = "";
              let regExp = new RegExp(
                converter("计时") + "(.+)" + converter("分钟")
              );
              if (regExp.test(this.userText)) {
                // setTimeout(() => {
                let _number = this.userText.match(regExp)[1];
                let _time = 0;
                if (!/^\d+$/.test(_number)) {
                  _time = this.chineseToNumber(_number) * 60;
                } else {
                  _time = parseInt(_numberList[1]) * 60;
                }
                this.$emit("startTime", _time);
                this.aiStatus = 0;
                this.showTextIndex = 0;
                this.aiText =
                  "好的，我已为您计时" +
                  this.userText.match(regExp)[1] +
                  "分钟。";
                this.userText = "";
                this.timer = setTimeout(() => {
                  this.showTextIndex = 3;
                  this.aiStatus = 2;
                  this.aiText = "";
                  this.userText = "";
                }, 3000);
                // }, 2000);
              } else {
								let msgList = [];

								msgList.push({
									role:"user",
									content: `请在150字以内回答以下问题：\n${this.userText}`
								})
                this.chatLoading = true;
                const _uuid = uuidv4();
                let params = {
                  model: "gpt-4o-2024-11-20",
                  temperature: 0,
                  max_tokens: 4096,
                  top_p: 1,
                  frequency_penalty: 0,
                  presence_penalty: 0,
                  messages: msgList,
                  uid: this.userId,
                  mind_map_question: "",
                  stream:true
                };

                  const md = new MarkdownIt();
                  let _this = this;
                  this.curRequestController = new AbortController();

                  let _allText = "";
                  let _mdText = "";
                  let _talkText = "";

                  fetchEventSource("https://gpt4.cocorobo.cn/chat_post_stream",{
                    method: "POST",
                    headers: {
                      "Content-Type": "application/json"
                    },
                    body: JSON.stringify(params),
                    signal: _this.curRequestController.signal,
                    onmessage(_e){
                      console.log('_e',_e)

                      _this.showIndex = 0;
                      if(!_e.data)return
                      let _eData = _e.data;
                      if (_eData.replace("'", "").replace("'", "") == "[DONE]") {
                        // this.source.close();
                        // this.source = null;
                        // let _result = [];
                        // if ("result" in _eData) {
                        //   _result = _eData.result;
                        //   for (let i = 0; i < _result.length; i++) {
                        //     _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
                        //   }
                        // }
                        _mdText = _mdText.replace("_", "");
                        _this.aiText = _mdText;
                        // _this.scrollBottom();
                        if (_talkText != "") {
                          let _resultText = _this.removeMarkdown(_talkText);
                          _this.talkTextList.push(_resultText);
                          _talkText = "";
                          if (!_this.talkLoading) _this.talkText();
                        }
                        _this.chatLoading = false;
                        _this.userText = '';
                      } else {
                        // _talkIndex+=1;
                        let _text = _eData.replace("'", "").replace("'", "");
                        if (_allText == "") {
                          _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
                          _talkText += _text.replace(/^\n+/, "");
                        } else {
                          _allText += _text;
                          _talkText += _text;
                        }
                        `~`;
                        _mdText = _allText + "_";
                        _mdText = _mdText.replace(/\\n/g, "\n");
                        _mdText = _mdText.replace(/\\/g, "");
                        if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
                        _this.aiText = _mdText;
                        _this.showTextIndex = 0;
                        // _this.scrollBottom();
                        if (/[，。：；？！）]/.test(_talkText)) {
                          let _resultText = _this.removeMarkdown(_talkText);
                          _this.talkTextList.push(_resultText);
                          _talkText = "";
                          if (!_this.talkLoading) _this.talkText();
                        }
                      }

                      // let _data = ev.data;
                      // if(_data=='[DONE]')return;
                      // _addText+=_data;
                      // this.aiText = md.render(_addText)
                      // // _this.chatList.find(i => i.uid == _uuid).aiContent =  md.render(_addText);
                      // // _this.chatList.find(i => i.uid == _uuid).loading = false;
                      // _this.scrollBottom();
                      // console.log(_data)
                    },
                    onclose(){
                      _this.$forceUpdate();
                      _this.userText = '';

                      // _this.stopTalkToken = null;
                      // // _this.faloading = false;
                      _this.curRequestController = null;

                      // _this.chatList.find(i => i.uid == _uuid).isalltext = true;
                      // _this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
                      // _this.insertChat(_uuid);
                      console.log("连接关闭")
                    },
                    onerror(err){

                      console.log("连接错误",err)
                    }
                })
                // this.ajax
                //   // .post("https://claude3.cocorobo.cn/chat", params)
                //   // .post("https://gpt4.cocorobo.cn/chat", params)
                //   .post(
                //     "https://gpt4.cocorobo.cn/ai_agent_park_chat_new",
                //     params
                //   )
                //   .then(res => {
                //     if (
                //       converter(res.data.FunctionResponse.result) ==
                //       converter("发送成功")
                //     ) {
                //       this.userText = "";
								// 			this.showIndex = 0;
                //     } else {
                //       // this.$message.warning(res.data.FunctionResponse.result);
                //       console.log(res.data.FunctionResponse.result);
                //       this.chatLoading = false;
                //       this.aiStatus = 0;
                //       this.showTextIndex = 0;
                //       this.aiText = "对不起，我无法理解您的问题，请重新提问";
                //       this.timer = setTimeout(() => {
                //         this.showTextIndex = 3;
                //         this.aiStatus = 2;
                //         this.aiText = "";
                //         this.userText = "";
                //       }, 3000);
                //     }
                //   })
                //   .catch(e => {
                //     console.log(e);
                //     this.chatLoading = false;
                //     this.aiStatus = 0;
                //     this.showTextIndex = 0;
                //     this.aiText = "对不起，我无法理解您的问题，请重新提问";
                //     this.timer = setTimeout(() => {
                //       this.showTextIndex = 3;
                //       this.aiStatus = 2;
                //       this.aiText = "";
                //       this.userText = "";
                //     }, 3000);
                //   });
                // // 通过流获取ai对话数据
                // this.getAtAuContent(_uuid);
              }
            }, 5000);
          }
        } else {
          console.log("不响应");
        }
      };
      // } catch (error) {
      //   console.log("ai录音报错👇");
      //   console.log(error);
      //   setTimeout(() => {
      //     this.recordStart();
      //   }, 1000);
      // }
    },
    stopRecord() {
      // this.$parent.changeRecordType(0);
      // this.$message.success("已关闭语音助手")
      // return
      try {
        let iiframe = this.$refs["iiframe"];
        iiframe.contentWindow.window.document
          .getElementById("scenarioStopButton")
          .click();
        // this.stopTalk();
        // 录音借宿
        iiframe.contentWindow.onSessionStopped = (s, e) => {
          this.isOpen = false;
          this.show = false;
          this.showTextIndex = 3;
          this.showIndex = 2;
          this.$parent.changeRecordType(0);
          this.$message.success("已关闭语音助手");
          if (this.talkLoading) {
            this.stopTalk();
          }
          this.userText = "";
          this.aiText = "";
        };

      } catch (error) {
        console.log(error)
        this.isOpen = false;
        this.show = false;
        this.showTextIndex = 3;
        this.showIndex = 2;
        this.$parent.changeRecordType(0);
        this.$message.success("已关闭语音助手");
        this.userText = "";
        this.aiText = "";
      }

    },
    chineseToNumber(chinese) {
      var OpenCC = require("opencc-js");
      let converter = OpenCC.Converter({
        from: "hk",
        to: "cn"
      });
      chinese = converter(chinese);
      const chineseNumbers = {
        零: 0,
        一: 1,
        二: 2,
        三: 3,
        四: 4,
        五: 5,
        六: 6,
        七: 7,
        八: 8,
        九: 9,
        十: 10,
        百: 100,
        千: 1000,
        万: 10000,
        亿: 100000000
      };

      let result = 0;
      let tempNum = 0; // 用于累积处理
      let sectionNum = 0; // 每个段的值

      for (let i = 0; i < chinese.length; i++) {
        const char = chinese[i];
        const num = chineseNumbers[char];

        if (num === undefined) {
          throw new Error(`Unexpected character: ${char}`);
        }

        if (
          num === 10 ||
          num === 100 ||
          num === 1000 ||
          num === 10000 ||
          num === 100000000
        ) {
          if (tempNum === 0) tempNum = 1; // 如果前面没有数，默认是1
          tempNum *= num;

          if (num === 10000 || num === 100000000) {
            sectionNum += tempNum;
            result += sectionNum;
            tempNum = 0;
            sectionNum = 0;
          }
        } else {
          tempNum += num;
        }
      }

      result += sectionNum + tempNum;
      return result;
    },
    removeMarkdown(text) {
      return text
        .replace(/[#*_~`>+\-]/g, "") // 移除 #、*、_、~、`、>、+、- 符号
        .replace(/!\[.*?\]\(.*?\)/g, "") // 移除图片
        .replace(/\[.*?\]\(.*?\)/g, "") // 移除链接
        .replace(/```[\s\S]*?```/g, "") // 移除代码块（不使用 s 标志）
        .replace(/`[^`]*`/g, "") // 移除行内代码
        .replace(/\d+\./g, "") // 移除有序列表
        .replace(/^\s*[-*+]\s+/gm, "") // 移除无序列表
        .replace(/\s+/g, " ") // 将多个空白字符替换为一个空格
        .trim(); // 去除字符串两端的空白字符
    },
    getAtAuContent(_uid) {
      this.source = new EventSource(
        `https://gpt4.cocorobo.cn/question/${_uid}`
      );
      //http://gpt4.cocorobo.cn:8011/question/   https://gpt4.cocorobo.cn/question/
      let _allText = "";
      let _mdText = "";
      let _talkText = "";
      // let _talkIndex = 0;
      // const md = new MarkdownIt();
      this.source.onmessage = _e => {
				this.showIndex = 0;
				this.aiStatus = 0
        let _eData = JSON.parse(_e.data);
        if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
          let _result = [];
          if ("result" in _eData) {
            _result = _eData.result;
            for (let i = 0; i < _result.length; i++) {
              _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
            }
          }
          _mdText = _mdText.replace("_", "");
          this.aiText = _mdText;
          if (_talkText != "") {
            let _resultText = this.removeMarkdown(_talkText);
            this.talkTextList.push(_resultText);
            _talkText = "";
            if (!this.talkLoading) this.talkText();
          }
          this.chatLoading = false;
          this.source.close();
        } else {
          // _talkIndex+=1;
          let _text = _eData.content.replace("'", "").replace("'", "");
          if (_allText == "") {
            _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
            _talkText += _text.replace(/^\n+/, "");
          } else {
            _allText += _text;
            _talkText += _text;
          }
          `~`;
          _mdText = _allText + "_";
          _mdText = _mdText.replace(/\\n/g, "\n");
          _mdText = _mdText.replace(/\\/g, "");
          if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
          this.aiText = _mdText;
          this.showTextIndex = 0;
          if (/[，。：；？！）]/.test(_talkText)) {
            let _resultText = this.removeMarkdown(_talkText);
            this.talkTextList.push(_resultText);
            _talkText = "";
            if (!this.talkLoading) this.talkText();
          }
        }
      };
    },
    talkText() {
      let _text = this.talkTextList.shift();
      let _talkTextIiframe2 = this.$refs.iiframe2;

      if (_text) {
        this.talkLoading = true;
        if (this.timer) {
          clearTimeout(this.timer);
          this.timer = null;
        }
        console.log(`👉转语音：${_text}`);
        _talkTextIiframe2.contentWindow.texttospeech(
          _text,
          this.talkText,
          this.endTalk
        );
      } else {
        _talkTextIiframe2.contentWindow.closesynthesizer();
      }
    },
    endTalk() {
      console.log("👉转语音结束👈");
      this.talkLoading = false;
    },
    stopTalk() {
      this.talkTextList = [];
      let _talkTextIiframe2 = this.$refs.iiframe2;
      _talkTextIiframe2.contentWindow.closesynthesizer();
      _talkTextIiframe2.contentWindow.pausesynthesizer();
      this.talkLoading = false;
    }
  },
  mounted() {
    // // this.recordStart()
    // setTimeout(()=>{
    // 	this.recordStart("可可同学。")
    // 	setTimeout(()=>{
    // 		this.recordStart("世界上最大的火山是什么。")
    // 		setTimeout(()=>{
    // 			this.recordStart("位于哪里。他温度怎么样。")
    // 		},2000)
    // 	},2000)
    // },5000)
  }
};
</script>

<style scoped>
.levitatedSphere {
  position: fixed;
  width: auto;
  height: auto;
  top: 20px;
  right: 10px;
  z-index: 9999;
  display: flex;
}

.ls_hello {
  width: 80px;
  height: 80px;
  position: absolute;
  top: 0;
  right: 0;
	cursor: pointer;
  animation: smallToBig 1s both;
}

/* 定义渐入动画 */
@keyframes smallToBig {
  from {
    opacity: 0;
    transform: scale(0.1);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.ls_text {
  position: absolute;
  right: 100px;
  top: 20px;
  max-width: 300px;
  display: flex;
  justify-content: flex-end;
}

.ls_t_ai {
  padding: 12px;
  width: auto;
  height: auto;
  border-radius: 12px 0px 12px 12px;
  background: #00000099;
  color: #fff;
}

.ls_t_user {
  padding: 12px;
  width: auto;
  height: auto;
  border-radius: 12px 12px 12px 12px;
  background: #00000099;
  color: #fff;
}
</style>
