<template>
  <section class="chat">
    <el-row align="middle mar-b16">
      <div class="modelInfo">
        <img :src="config.model.avatar" alt=""/>
        <div class="fill mar-l8">
          <b v-text="config.model.name"/>
          <div class="desc" v-text="config.model.desc"/>
        </div>
      </div>
      <el-row justify="end" class="fill mar-l8 gap-8">
        <!--聊天操作栏-->
        <div class="optIcon clear"/>
        <div class="optIcon setting" @click="$emit('setting')"/>
      </el-row>
    </el-row>
    <thinking-bar v-show="loading"/>
    <chat-content class="fill" :list="chatHistory"/>
    <el-row class="mar-t8" align="middle">
      <chat-input class="fill mar-r8" v-model="inputText" @enter="handleSend"/>
      <el-button type="primary" @click="handleSend">发送</el-button>
    </el-row>
  </section>
</template>

<script>
import {dayjs} from "element-plus";
import ChatContent from "../components/chatContent";
import ChatInput from "../components/chatInput";
import ThinkingBar from "../components/thinkingBar";
import {USER_AVATAR} from "../utils/env";

export default {
  name: "chat",
  components: {ChatContent, ChatInput, ThinkingBar},
  props: {
    config: {default: () => ({})}
  },
  data() {
    return {
      loading: false,
      inputText: "",
      chatHistory: []
    }
  },
  methods: {
    handleSend() {
      if (!!this.inputText) {
        const ai = this.config.model
        const myMsg = {
          avatar: USER_AVATAR,
          name: "我",
          time: dayjs().format("YYYY-MM-DD HH:mm:ss"),
          msg: this.inputText,
          chatType: 0, //信息类型，0文字，1图片
          uid: "me", //uid
          role: "user"
        }
        this.chatHistory.push(myMsg)
        this.loading = true
        const aiMsg = {
          avatar: ai.avatar,
          name: ai.name,
          time: dayjs().format("YYYY-MM-DD HH:mm:ss"),
          msg: "",
          chatType: 0, //信息类型，0文字，1图片
          uid: "ai", //uid
          role: "assistant"
        }
        this.chatHistory.push(aiMsg)
        if (this.config.stream) {
          ai.chatStream(this.chatHistory).then(reader => this.streamOutput(reader, this.chatHistory.at(-1))).finally(() => this.loading = false)
        } else {
          ai.chat(this.chatHistory).then(reply => {
            const decodeArr = reply.split("")
            decodeArr.forEach(e => this.chatHistory.at(-1).msg += e)
          }).finally(() => this.loading = false)
        }
      } else {
        this.$message.error("请不要发送空消息!")
      }
    },
    streamOutput(reader, chat) {
      return reader.read().then(({done, value}) => {
        if (done) {
          return;
        }
        if (!chat.reminder) {
          chat.reminder = ""
        }
        let decode = new TextDecoder().decode(value)
        decode = chat.reminder + decode
        let decodedArray = decode.split("data: ");
        let longstr = "";
        decodedArray.forEach(decoded => {
          decoded = decoded.trim();
          try {
            if (longstr != "") {
              decoded = longstr + decoded;
              longstr = "";
            }
          } catch (e) {
            longstr = decoded;
            decoded = "";
          }
          if (!!decoded && decoded !== "[DONE]") {
            const choices = JSON.parse(decoded).choices
            if (choices?.length > 0) {
              const response = choices[0].delta.content || "";
              chat.msg += response
            }
          }
        })
        return this.streamOutput(reader, chat)
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.chat {
  color: #fff;
  display: flex;
  flex-direction: column;

  .modelInfo {
    display: flex;
    align-items: center;
    line-height: 1.4;

    & > img {
      border: 2px solid #fff;
      border-radius: 50%;
      padding: 4px;
      width: 45px;
      height: 45px;
    }

    b {
      font-size: 20px;
    }

    .desc {
      color: #999;
      font-size: 14px;
    }
  }

  .optIcon {
    box-sizing: border-box;
    height: 40px;
    min-width: 40px;
    background-size: 24px 24px;
    background-repeat: no-repeat;
    background-position: top center;
    cursor: pointer;
    opacity: .6;
    padding-top: 24px;

    &:after {
      font-size: 12px;
      display: block;
      text-align: center;
    }

    &:hover {
      opacity: 1;
    }

    &.clear {
      background-image: url("../assets/clear.svg");

      &:after {
        content: "清空历史";
      }
    }

    &.setting {
      background-image: url("../assets/setting.svg");

      &:after {
        content: "设置";
      }
    }
  }
}
</style>
