<template>
  <div class="chat bg-gray-900 comBg">
    <div class="flex flex-col items-center justify-center h-screen px-4">
      <!-- onClick={() => navigate('/')} -->
      <div
        class="text-white px-3 py-2 rounded-lg mb-4 absolute top-2 left-2"
        style="background-color: var(--bg-color1);"
        @click="goBack"
      >
        <!-- <i class="fas fa-chevron-left mr-2"></i> -->
        返回
      </div>
      <div class="content">
        <div class="leftImg">
          <img :src="baseApi + info.picture" alt="">
          <div class="aiInfo">
            <span class="photo">
              <img :src="baseApi + info.picture">
            </span>
            <div class="info">
              <div class="name">{{ info.characterName }}</div>
              <div class="tags">
                <span class="tag" v-for="(item, index) in info.labelArr" :key="index">
                  {{ item }}
                </span>
              </div>
              <div class="infoContent">{{ info.prologue }}</div>
            </div>
          </div>
        </div>
        <div class="chat-box"> 
          <div class="messages" ref="messages">
            <template v-for="(item, index) in returnMessage">
              <div v-if="item.role == 'assistant'" class="text-white mb-4 flex" :key="index">
                <!-- ai返回的信息 -->
                <div class="pt-2 photo">
                  <img
                    :src="baseApi + info.picture"
                    class="rounded-full w-14 h-14 object-cover"
                  />
                </div>
                <div class="message fex-1 ml-4 mt-2 p-2 rounded-r-md rounded-bl-md text-xs" >
                  <div v-show="!item.content" class="loadingMessage" >
                    <div v-loading="!item.content" element-loading-background="rgba(0, 0, 0, 0.0)"></div>
                  </div>
                  <p v-show="item.content">{{ item.content }} </p>
                </div>
              </div>
              <!-- 用户发送的信息 -->
              <div v-if="item.role == 'user'" class="text-white mb-4 flex me" :key="index">
                <div class="pt-2 photo">
                  <img
                    src="@/assets/images/default_avatar_user.png"
                    class="rounded-full w-14 h-14 object-cover"
                  />
                </div>
                <div class="message fex-1 mr-4  mt-2 p-2 rounded-l-md rounded-br-md text-xs">
                  <p>{{ item.content }}</p>
                </div>
              </div>
            </template>
          </div>
          
          <div class="absolute left-2 right-2 bottom-4 ">
            <!-- <div class="flex items-center text-gray-400 text-xs mb-4 ">
              <span>@Leon S Kennedy - Resident Evil</span>
            </div> -->
            <div class="flex">
              <el-button class="buttonBg1 mButton" @click="newStart" style="margin-right: 5px;" type="primary" round icon="el-icon-plus"></el-button>
              <input
                type="text"
                placeholder="输入消息..."
                class="flex-1 py-2 px-4 rounded-l-lg text-sm text-white focus:outline-none"
                style="background: #ffffff0f; border: 1px solid #5b5b5e;"
                v-model="content"
                @keydown="Enterkey"
              />
              <button @click="getStreamChatWithWeb" class="buttonBg1 text-white px-4 rounded-r-lg text-sm">
                发送
              </button>
              
            </div>
          </div>
        </div>
      </div>
      
    </div>
  </div>
</template>

<script>
import { streamChatWithWebApi } from "@/api/chat.js"
import { detailApi } from "@/api/detail.js"
export default {
  data() {
    return {
      info: {},
      messageLoading: false,
      returnMessage: [],
      content: ''
    }
  },
  mounted() {
    if (this.$route.query.characterId) {
      this.getDetail(this.$route.query.characterId)
    }
  },
  watch: {
    returnMessage: {
      handler(newVal, lodVal) {
        this.$nextTick(() => {
          let messages = this.$refs.messages
          messages.scrollTop = messages.scrollHeight
        })
      },
      deep: true
    }
  },
  methods: {
    getDetail(id) {
      detailApi(id).then(res => {
        console.log(res, '角色详情');
        this.info = res.data
        let HistoryMessage = JSON.parse(localStorage.getItem(`[${123},${this.info.id}]`));
        if (HistoryMessage) {
          this.returnMessage = HistoryMessage
        } else {
          this.returnMessage.push({
            role: 'assistant',
            content: this.info.firstContent
          })
          localStorage.setItem(`[${123},${this.info.id}]`, JSON.stringify(this.returnMessage));
        }
      })
    },
    goBack() {
      this.$router.back()
    },
    newStart() {
      // 清空历史数据
      localStorage.removeItem(`[${123},${this.info.id}]`);
      this.returnMessage = []
      this.getDetail(this.info.id)
    },
    Enterkey(e) {
      if (e.keyCode == 13) {
        this.getStreamChatWithWeb()
      }
    },
    async getStreamChatWithWeb_old() {
      this.messageLoading = true
      if (!this.content) {
        return
      }
      this.returnMessage.push({
        role: 'user',
        content: this.content
      })
      let HistoryMessage = JSON.parse(localStorage.getItem(`[${123},${this.info.id}]`));
      // 历史记录取最新的20条传给后端
      if (HistoryMessage && HistoryMessage.length > 20) {
        HistoryMessage = HistoryMessage.slice(HistoryMessage.length - 1, 20)
      }
      let params = {
        historyMessage: HistoryMessage || [],
        characterId: this.info.id,
        prompt: JSON.parse(JSON.stringify(this.content))
      }
      // 清空输入框的值
      this.content = ''
      // 新增一条ai信息
      this.returnMessage.push({
        role: 'assistant',
        content: ''
      })
      let res = await streamChatWithWebApi(params)
      console.log(res.data.message.content, 'res');
      let content = res.data.message.content
      let index = 0
      let xing = 1
      let messageInterval = setInterval(() => {
        if (index > content.length - 1) {
          console.log('结束');
          // 消息全部显示后存到历史localStorage
          let HistoryMessage = []
          // 历史只存100条，长度超出截取最新的
          if (this.returnMessage.length > 100) {
            HistoryMessage = JSON.stringify(this.returnMessage.slice(this.returnMessage.length - 100, 100))
          } else {
            HistoryMessage = JSON.stringify(this.returnMessage)
          }
          localStorage.setItem(`[${123},${this.info.id}]`, HistoryMessage);

          clearInterval(messageInterval)
          return
        }
        console.log(content[index], 'content[index]');
        if (content[index] == "*") {
          if (xing == 1) {
            xing = 2
            this.returnMessage[this.returnMessage.length - 1].content += "("
          } else if (xing == 2) {
            xing = 1
            this.returnMessage[this.returnMessage.length - 1].content += ")"
          }
        } else {
          this.returnMessage[this.returnMessage.length - 1].content += content[index]
        }
        index += 1
      }, 50)
    },
    async getStreamChatWithWeb() {
      this.messageLoading = true
      if (!this.content) {
        return
      }
      this.returnMessage.push({
        role: 'user',
        content: this.content
      })
      let HistoryMessage = JSON.parse(localStorage.getItem(`[${123},${this.info.id}]`));
      // 历史记录取最新的20条传给后端
      if (HistoryMessage && HistoryMessage.length > 20) {
        HistoryMessage = HistoryMessage.slice(HistoryMessage.length - 1, 20)
      }
      let params = {
        HistoryMessage: HistoryMessage || [],
        characterId: this.info.id,
        prompt: this.content
      }
      // 新增一条ai信息
      this.returnMessage.push({
        role: 'assistant',
        content: ''
      })
      // 清空输入框的值
      this.content = ''

      let res = await streamChatWithWebApi(params)
      console.log(res, 'res');
      this.messageLoading = false
      
      if (res.status != 200) {
        this.$message.error(res.statusText)
        this.returnMessage.splice(this.returnMessage.length - 1, 1)
        return
      }
      const reader = res.body.getReader()
      const decoder=new TextDecoder()
      while(1){
        const {done, value} = await reader.read()
        // console.log(done, 'done');
        if(done){
          console.log(value, 'value');
          // if (typeof(value) == "undefined") {
          //   this.$message.error('错误')
          //   this.returnMessage.splice(this.returnMessage.length - 1, 1)
          // }
          console.log('结束');
          // 消息全部显示后存到历史localStorage
          let HistoryMessage = []
          // 历史只存100条，长度超出截取最新的
          if (this.returnMessage.length > 100) {
            HistoryMessage = JSON.stringify(this.returnMessage.slice(this.returnMessage.length - 100, 100))
          } else {
            HistoryMessage = JSON.stringify(this.returnMessage)
          }
          localStorage.setItem(`[${123},${this.info.id}]`, HistoryMessage);
          break;
        }
        
        //txt就是一个一个的字 然后添加到页面上就可以了
        const txt = decoder.decode(value).split('data:')
        // const txt = decoder.decode(value)
        this.addMessage(txt)
        // let data = JSON.parse(txt).message.content
        // console.log(txt, 'txt');
        // if (this.isJSON(txt) && JSON.parse(txt).code != 200) {
        //   let data = JSON.parse(txt)
        //   this.$message.error(data.msg)
        //   this.returnMessage.splice(this.returnMessage.length - 1, 1)
        //   break;
        // }
        
      }
    },
    addMessage(value) {
      for (let i = 0; i < value.length; i++) {
        const element = value[i];
        if (this.isJSON(element)) {
          let txt = JSON.parse(element).content
          this.returnMessage[this.returnMessage.length - 1].content += txt
        }
      }
    },
    isJSON(str) {
      if (typeof str == 'string') {
          try {
              JSON.parse(str);
              return true;
          } catch(e) {
              // console.log(e);
              return false;
          }
      }
    },
  }
}
</script>

<style lang="scss" scoped>

.chat {
  min-height: 100vh;
}
.content {
  margin-top: 30px;
  background-size: 100% 100%;
  display: flex;
  height: 90vh;
  justify-content: center;
  width: 100vw;
  
  >.leftImg {
      border-radius: 16px 16px 16px 16px;
      height: 95%;
      position: relative;
      min-width: 380px;

      >img {
        border: 6px solid;
        border-image: linear-gradient(180deg, #b48733, #e8cf97, #b48733) 6 6;
        height: 99%;
        margin-right: 5px;
      }
      >.aiInfo {
        background-color: #ffffff1a;
        border-radius: 24px 24px 24px 24px;
        bottom: -70px;
        display: flex;
        height: 193px;
        justify-content: center;
        left: 50%;
        position: absolute;
        transform: translate(-50%, -50%);
        width: 100%;

        >.photo {
          width: 64px;
          height: 64px;
          font-size: 18px;
          position: absolute;
          top: -20px;
          box-sizing: border-box;
          margin: 0;
          padding: 0;
          color: #fff;
          line-height: 1.5714285714285714;
          list-style: none;
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
          display: inline-flex;
          justify-content: center;
          align-items: center;
          overflow: hidden;
          white-space: nowrap;
          text-align: center;
          vertical-align: middle;
          background: rgba(0, 0, 0, 0.25);
          border: 1px solid transparent;
          border-radius: 50%;
        }
        >.info {
          padding-top: 50px;
          width: 80%;
          >.name {
            color: #fff;
            font-size: 22px;
            font-style: normal;
            font-weight: 700;
            line-height: 31px;
            text-align: center;
            text-transform: none;
          }
          >.tags {
            padding-bottom: 8px;
            text-align: center;
            >.tag {
              margin-right: 4px;
              background: #ffffff1a;
              border-radius: 4px 4px 4px 4px;
              color: #fff;
              font-size: 12px;
              font-weight: 500;
              line-height: 17px;
              border-color: transparent;
            }
          }
          >.infoContent {
            color: #fff;
            font-size: 16px;
            font-style: normal;
            font-weight: 500;
            height: 80px;
            line-height: 22px;
            overflow-y: auto;
            text-align: center;
            text-transform: none;
          }
        }
      }
  }
  >.chat-box {
    margin-left: 5px;
    position: relative;
    background-color: #ffffff1a;
    background-position: 50%;
    background-repeat: no-repeat;
    background-size: auto;
    border: 1px solid #635677 !important;
    border-radius: 20px;
    box-sizing: border-box;
    color: #fff !important;
    display: flex;
    flex-direction: column;
    height: 95%;
    // margin: 0 auto;
    width: 1010px;
    padding: 25px;
  }
}

.messages {
  height: calc(100% - 68px );
  overflow-y: auto;
}
.messages::-webkit-scrollbar {
  width: 0px;
}
.message {
  background: #ffffff0f;
  border: 1px solid #5b5b5e;
  max-width: calc(100% - 72px);
  // flex: 1;
  min-width: 80px;
}
.photo {
  width: 56px;
}
.me {
  flex-direction: row-reverse;
}
.loadingMessage {
  position: relative;
  // display: flex;
  // justify-content: center;
  width: 100%;
  height: 100%;
}
</style>
<style scoped>
  .loadingMessage >>> .el-loading-parent--relative {
    width: 100%;
    height: 100%;
    
  }
  .loadingMessage >>> .el-loading-spinner {
    display: flex;
    justify-content: center;
  }
  .mButton {
    border: solid 0px;
  }
</style>