<template>
  <div class="bindFrom" v-loading="loading">
    <bar @cutPage="cutPage" :tit="'AI对话'" :backPage="0"></bar>
    <div class="con" ref="chatAreaRef">
      <template v-for="(item, index) in chatList">
        <div class="chat1" style="justify-content: flex-end;" v-if="item.content">
          <div class="conText">
            <div class="Txt" v-html="item.content"></div>
            <img
              style="position: absolute;left: -25px;bottom: -10px;"
              src="../../assets/images/classObserve/copyTextZ.png"
              alt=""
              @click.stop="copy(item.content)"
            />
            <div class="DateT" style="right: 0 !important;">{{ item.createtime }}</div>
          </div>
          <div class="PicturePop">
            <img src="../../assets/images/classObserve/userAvatar.png" alt="" />
          </div>
        </div>
        <div class="chat1">
          <div class="PicturePop">
            <img :src="item.filename?item.filename:require('../../assets/images/classObserve/ai.png')" alt="" />
          </div>
          <div class="conText" v-loading="item.loading">
            <div class="Txt" v-html="item.aiContent"></div>
            <img
              style="position: absolute;right: -25px;bottom: -10px;"
              src="../../assets/images/classObserve/copyTextZ.png"
              alt=""
              @click.stop="copy(item.aiContent)"
            />
            <div class="DateT">{{ item.createtime }}</div>
          </div>
        </div>
      </template>
      <!-- <div class="langBtn">
        <img src="../../assets/images/classObserve/langcut.png" alt="" />
        <span>普通话</span>
      </div> -->
    </div>
    <div class="bot" v-loading="chatLoading">
      <div class="b_roleList" v-if="showRoleList && choseRoleList.length > 0">
        <div class="b_rl_item" v-for="item in choseRoleList" :key="item.id" @click.stop="choiceRole(item)">
          <img :src="item.headUrl?item.headUrl:require('../../assets/images/classObserve/ai.png')" />
          <div class="b_rl_i_message">
            <div>{{ item.assistantName }}</div>
            <span>作者：{{ item.username }}</span>
            <div class="des">{{ item.description }}</div>
          </div>
        </div>
      </div>
      <!-- <img class="pict1" src="../../assets/images/classObserve/maike.png" alt="" /> -->
      <el-input
        ref="textareaRef"
        v-model="inputValue"
        @input="inputChange"
        placeholder="请在此输入您想了解的内容"
      ></el-input>
      <img class="pict2" src="../../assets/images/classObserve/sendimg.png" alt="" @click.stop="send" />
    </div>
  </div>
</template>

<script>
import bar from './components/bar.vue'
import fromList from './components/fromList'
import {
  getChatListRequest,
  insertChatListRequest,
  aiChatRequest,
  getRoleList,
  getShareRoleList,
	aiRoleChatRequest
} from '@/api/classObserve'
import { v4 as uuidv4 } from 'uuid'
import MarkdownIt from 'markdown-it'

export default {
  components: {
    bar,
    fromList
  },
  props: {
    page: {
      type: Number,
      default: 1
    },
    tid: {
      type: String,
      default: ''
    },
		fileId:{
			type:String,
			default:""
		},
  },
  data() {
    return {
      selectValue: '',
      inputValue: '',
      loading: false,
      chatLoading: false,
      chatList: [],
      userId: this.$store.state.user.id,
      publicRoleList: [],
      roleList: [],
      showRoleList: false
    }
  },
  computed: {
    // 选择可以@的角色
    choseRoleList() {
      let result = []
      this.roleList.map(i => result.push(i))
      this.publicRoleList.map(i => result.push(i))
      const _index = this.inputValue.lastIndexOf('@')
      if (_index !== -1) {
        let roleName = this.inputValue.substring(_index + 1)
        result = result.filter(i => i.assistantName.indexOf(roleName) != -1)
      } else {
        result = []
      }
      return result
    }
  },
  methods: {
    cutPage() {
      this.$emit('cutPage', 1)
    },
    send() {
      var OpenCC = require('opencc-js')
      let converter = OpenCC.Converter({
        from: 'cn',
        to: 'hk'
      })
      // return console.log(this.inputValue)
      let _text = this.inputValue
      this.inputValue = ''
      if (!_text) return this.$toast('请输入内容')

      let _atRoleList = []
			let _roleList = []
			this.roleList.map(i=>_roleList.push(i))
			this.publicRoleList.map(i=>_roleList.push(i))
			// let _roleList = [...this.roleList, ...this.publicRoleList];
      _roleList.forEach((i) => {
        if (_text.indexOf(`@${i.assistantName}`) != -1) {
          _atRoleList.push(i);
        }
      });
      if (_atRoleList.length > 0) {
        //有@角色
        let _replaceText = _text
        let _htmlText = _text
        _atRoleList.forEach(_i => {
          _replaceText = _replaceText.replaceAll(`@${_i.assistantName}`, ``)
          _htmlText = _htmlText.replaceAll(
            `@${_i.assistantName}`,
            `<span class='aite-name'>@${_i.assistantName}</span>`
          )
        })
        _atRoleList.forEach((_item, _index) => {
          const _uid = uuidv4()
          if (_index == 0) {
            this.chatList.push({
              loading: true,
              role: 'user',
              content: _htmlText,
              uid: _uid,
              AI: 'AI',
              aiContent: '',
              oldContent: '',
              isShowSynchronization: false,
              filename: _item.headUrl,
              index: this.chatList.length,
              is_mind_map: false,
              fileid: _item.assistantName,
              createtime: new Date().toLocaleString().replaceAll('/', '-')
            })
          } else {
            this.chatList.push({
              loading: true,
              role: 'user',
              content: '',
              uid: _uid,
              AI: 'AI',
              aiContent: '',
              oldContent: '',
              isShowSynchronization: false,
              filename: _item.headUrl,
              index: this.chatList.length,
              is_mind_map: false,
              fileid: _item.assistantName,
              createtime: new Date().toLocaleString().replaceAll('/', '-')
            })
          }
          this.scrollBottom()
          let params = {
            assistant_id: _item.assistant_id,
            userId: this.userId,
            message: _replaceText,
            session_name: `${this.tid}-classroomObservation`,
            uid: _uid,
            file_ids: this.fileId ? [this.fileId] : [],
            model: 'gpt-4o-2024-08-06'
          }
          aiRoleChatRequest(params)
            .then(res => {
              if (converter(res.FunctionResponse.result) == converter('发送成功')) {
              } else {
                this.$toast.fail(res.FunctionResponse.result)
              }
            })
            .catch(err => {
              console.log(err)
            })
          this.getAtAuContent(_uid, _htmlText, _item.headUrl, _item.assistantName)
        })
      } else {
        //未@角色
        let _uuid = uuidv4()
        this.chatList.push({
          role: 'user',
          content: `${_text}`,
          uid: _uuid,
          AI: 'AI',
          aiContent: '',
          oldContent: '',
          isShowSynchronization: false,
          filename: '',
          index: this.chatList.length,
          is_mind_map: false,
          createtime: new Date().toLocaleString().replaceAll('/', '-'),
          loading: true
        })
        this.scrollBottom()

        // 连续对话
        let _historyMessage = []
        // this.chatList.forEach(i=>{

        // })
        _historyMessage.push({ role: 'user', content: _text })
        let params = JSON.stringify({
          model: 'gpt-4o-2024-08-06',
          temperature: 0,
          max_tokens: 4096,
          top_p: 1,
          frequency_penalty: 0,
          presence_penalty: 0,
          messages: _historyMessage,
          uid: _uuid,
          mind_map_question: ''
        })

        aiChatRequest(params)
          // .post("https://claude3.cocorobo.cn/chat", params)
          .then(res => {
            if (converter(res.FunctionResponse.result) == converter('发送成功')) {
            } else {
              this.$toast.fail(res.FunctionResponse.result)
            }
          })
          .catch(e => {
            console.log(e)
          })
        this.getAiContent(_uuid)
      }
    },
    scrollBottom() {
      this.$nextTick(() => {
        // this.textareaChange();
        // this.$refs.tapeRef.$el.querySelector(
        //   ".t-chartArea"
        // ).scrollTop = this.$refs.tapeRef.$el.querySelector(".t-chartArea").scrollHeight;
        this.$refs.chatAreaRef.scrollTop = this.$refs.chatAreaRef.scrollHeight
      })
    },
    getChatList() {
      return new Promise((resolve, reject) => {
        if (!this.tid) return
        if (this.chatLoading) return this.$toast('请稍等...')
        this.chatList = []
        this.chatLoading = true
        this.loading = true
        let params = {
          userid: this.userId,
          groupid: '602def61-005d-11ee-91d8-005056b8q12w',
          // session_name:``
          session_name: `${this.tid}-classroomObservation`
        }
        getChatListRequest(params)
          .then(res => {
            let _data = JSON.parse(res.FunctionResponse)
            if (_data.length > 0) {
              let _chatList = []
              for (let i = 0; i < _data.length; i++) {
                _chatList.push({
                  loading: false,
                  role: 'user',
                  content: _data[i].problem,
                  uid: _data[i].id,
                  AI: 'AI',
                  aiContent: _data[i].answer,
                  oldContent: _data[i].answer,
                  isShowSynchronization: false,
                  filename: _data[i].filename,
                  index: i,
                  is_mind_map: false,
                  fileid: _data[i].fileid,
                  createtime: _data[i].createtime
                })
              }
              this.chatList = _chatList
              this.chatLoading = false
            } else {
              //没有对话记录
              this.chatLoading = false
            }
            resolve()
            this.loading = false
            this.scrollBottom()
          })
          .catch(err => {
            console.log(err)
            this.$toast.fail('获取对话记录失败')
            this.chatLoading = false
            this.scrollBottom()
            this.loading = false
            resolve()
          })
      })
    },
    copy(content) {
      // 创建临时textarea元素
      const tempInput = document.createElement('textarea')
      tempInput.value = content.replace(/<[^>]+>/g, '') // 设置要复制的内容
      // 隐藏元素
      tempInput.style.position = 'absolute'
      tempInput.style.left = '-9999px'
      // 将元素添加到DOM中
      document.body.appendChild(tempInput)
      // 选中元素内容
      tempInput.select()
      // 执行复制操作
      document.execCommand('copy')
      // 移除临时元素
      document.body.removeChild(tempInput)
      this.$toast.success('复制成功')
    },
    getAiContent(_uid) {
      // let _source = new EventSource(
      // 	`https://claude3.cocorobo.cn/streamChat/${_uid}`
      // );
      let _source = new EventSource(`https://gpt4.cocorobo.cn/stream/${_uid}`) //http://gpt4.cocorobo.cn:8011/stream/     https://gpt4.cocorobo.cn/stream/
      let _allText = ''
      let _mdText = ''
      const md = new MarkdownIt()
      _source.onmessage = _e => {
        if (_e.data.replace("'", '').replace("'", '') == '[DONE]') {
          //对话已经完成
          _mdText = _mdText.replace('_', '')
          _source.close()
          this.chatList.find(i => i.uid == _uid).aiContent = _mdText
          this.chatList.find(i => i.uid == _uid).isalltext = true
          this.chatList.find(i => i.uid == _uid).isShowSynchronization = true
          this.chatList.find(i => i.uid == _uid).loading = false
          this.insertChat(_uid)
          return
        } else {
          //对话还在继续
          let _text = ''
          _text = _e.data.replaceAll("'", '')
          if (_allText == '') {
            _allText = _text.replace(/^\n+/, '') //去掉回复消息中偶尔开头就存在的连续换行符
          } else {
            _allText += _text
          }
          _mdText = _allText + '_'
          _mdText = _mdText.replace(/\\n/g, '\n')
          _mdText = _mdText.replace(/\\/g, '')
          if (_allText.split('```').length % 2 == 0) _mdText += '\n```\n'
          //转化返回的回复流数据
          _mdText = md.render(_mdText)
          this.chatList.find(i => i.uid == _uid).aiContent = _mdText
          this.chatList.find(i => i.uid == _uid).loading = false
          this.scrollBottom()
          // 处理流数据
        }
      }
    },
    getAtAuContent(_uid, _text, _headUrl, _assistantName) {
      let _source = new EventSource(`https://gpt4.cocorobo.cn/question/${_uid}`) //http://gpt4.cocorobo.cn:8011/question/   https://gpt4.cocorobo.cn/question/
      let _allText = ''
      let _mdText = ''
      const md = new MarkdownIt()
      _source.onmessage = _e => {
        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.chatList.find(i => i.uid == _uid).aiContent = _mdText
          this.chatList.find(i => i.uid == _uid).isalltext = true
          this.chatList.find(i => i.uid == _uid).isShowSynchronization = true
          this.chatList.find(i => i.uid == _uid).loading = false
          this.scrollBottom()
          this.insertChat(_uid)
        } else {
          let _text = _eData.content.replace("'", '').replace("'", '')
          if (_allText == '') {
            _allText = _text.replace(/^\n+/, '') //去掉回复消息中偶尔开头就存在的连续换行符
          } else {
            _allText += _text
          }
          _mdText = _allText + '_'
          _mdText = _mdText.replace(/\\n/g, '\n')
          _mdText = _mdText.replace(/\\/g, '')
          if (_allText.split('```').length % 2 == 0) _mdText += '\n```\n'
          //转化返回的回复流数据
          _mdText = md.render(_mdText)
          this.chatList.find(i => i.uid == _uid).aiContent = _mdText
          this.chatList.find(i => i.uid == _uid).loading = false
          this.scrollBottom()
          // 处理流数据
        }
      }
    },
    inputChange() {
      if (this.inputValue.at(-1) == '@') {
        this.showRoleList = true
      }
    },
    choiceRole(_data) {
      let _lastAtIndex = this.inputValue.lastIndexOf('@')
      this.inputValue = `${this.inputValue.slice(0, _lastAtIndex)}@${_data.assistantName} `
      this.$refs.textareaRef.focus()
      this.showRoleList = false
    },
    //保存消息
    insertChat(_uid) {
      let _data = this.chatList.find(i => i.uid == _uid)
      if (!_data) return
      let params = {
        userId: this.userId,
        userName: 'qgt',
        groupId: '602def61-005d-11ee-91d8-005056b8q12w',
        answer: _data.aiContent,
        problem: _data.content,
        file_id: _data.fileid ? _data.fileid : '',
        alltext: _data.aiContent,
        type: 'chat',
        filename: _data.filename,
        session_name: `${this.tid}-classroomObservation`
      }
      insertChatListRequest(params).then(res => {})
    },
    //获取角色
    getRoleList() {
      this.roleList = []
      let params = {
        userId: this.userId
      }
      getRoleList(params)
        .then(res => {
          let _data = res.FunctionResponse.result
          if (_data) {
            this.roleList = JSON.parse(_data)
          }
        })
        .catch(e => {
          console.log(e)
          // this.$message.error("获取角色列表失败");
          this.roleList = []
        })
    },
    getPublicRoleList() {
      this.publicRoleList = []
      let params = {
        userId: this.userId,
        organizeid: '45facc0a-1211-11ec-80ad-005056b86db5'
      }
      getShareRoleList(params)
        .then(res => {
          let _data = res.FunctionResponse.result
          if (_data) {
            this.publicRoleList = JSON.parse(_data)
          }
        })
        .catch(e => {
          this.publicRoleList = []
          console.log(e)
          // console.log("获取公共角色失败", e);
        })
    }
  },
  mounted() {
    this.getChatList()
    this.getRoleList()
    this.getPublicRoleList()
    this.roleList = []
    this.publicRoleList = []
  }
}
</script>

<style lang="scss" scoped>
.bindFrom {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100vh;
}
.con {
  height: calc(100vh - 50px - 60px);
  margin-top: 50px;
  padding: 20px 10px;
  box-sizing: border-box;
  position: relative;
  overflow: auto;
  background-image: linear-gradient(to bottom, #fff 0%, #ebf1fd 100%);
  .chat1 {
    display: flex;
    margin-bottom: 30px;
    .PicturePop {
      border-radius: 50%;
      border: 1px rgba(54, 129, 252, 1) solid;
      width: 30px;
      height: 30px;
      overflow: hidden;
      flex-shrink: 0;
      margin-right: 5px;
      margin-left: 5px;
      img {
        width: 100%;
        height: 100%;
      }
    }
    .conText {
      width: 80%;
      position: relative;
      .Txt {
        background-color: rgba(246, 249, 255, 1);
        padding: 10px 15px;
        box-sizing: border-box;
        font-size: 13px;
        border-radius: 2px;
        :deep(*) {
          margin: 0;
        }
				:deep(.aite-name){
					background-color: #1B5AAF;
					padding: 3px;
					font-size: 10px;
					color: #fff;
					border-radius: 2px;
				}
      }
      .DateT {
        color: rgba(0, 0, 0, 0.4);
        font-size: 10px;
        font-weight: 400;
        position: absolute;
        bottom: -15px;
        left: 0;
      }
    }
  }
  .langBtn {
    position: absolute;
    bottom: 10px;
    left: 10px;
    background-color: #fff;
    font-size: 14px;
    color: rgba(0, 0, 0, 0.9);
    padding: 5px 10px;
    border-radius: 30px;
    display: flex;
    align-items: center;
    img {
      width: 20px;
      height: 20px;
      margin-right: 3px;
    }
  }
}

.bot {
  height: 60px;
  display: flex;
  justify-content: center;
  padding: 10px 10px;
  align-items: center;
  box-sizing: border-box;
  position: relative;
  .b_roleList {
    width: 100%;
    max-height: 50vh;
    height: auto;
    position: absolute;
    bottom: 100%;
    border-radius: 10px 10px 0 0;
    background-color: #fff;
    padding: 10px;
    box-sizing: border-box;
    overflow: auto;
    .b_rl_item {
      width: 100%;
      height: 60px;
      margin-bottom: 10px;
      background-color: #fff;
      border-radius: 8px;
      transition: 0.3s;
      display: flex;
      align-items: center;
      padding: 0 10px;
      box-sizing: border-box;
      img {
        width: 50px;
        height: 50px;
        margin-right: 10px;
        border-radius: 50%;
      }
      .b_rl_i_message {
        width: 80%;
        height: 50px;
        display: flex;
        flex-direction: column;
        div {
          font-size: 14px;
        }
        .des {
          font-size: 10px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          width: 80%;
        }
        span {
          font-size: 10px;
          color: gray;
        }
      }
      &:active {
        background-color: #ebf1fd;
      }
    }
  }
  .pict1 {
    width: 24px;
    height: 24px;
    padding: 10px;
  }
  .pict2 {
    width: 35px;
    height: 35px;
    padding: 5px;
    margin-left: 5px;
  }
  .el-input__inner {
    border-radius: 30px !important;
  }
}
</style>
