<template>
  <div class="d-flex flex-column" style="height: 100%">
    <v-banner single-line>
      <div class="my-3">
        {{ title }}
      </div>
      <template #actions>
        <slot name="title"></slot>
      </template>
    </v-banner>
    <div style="flex: 1; overflow: auto;" class="pa-3" ref="box">
      <div style="height: 100%;">
        <v-list three-line>
          <!-- 欢迎语 -->
          <v-list-item>
            <v-list-item-content>
              <v-list-item-title class="d-flex align-center" :class="system.nameColor + '--text'">
                <v-icon class="mr-3" :color="system.iconColor" >
                {{ system.icon }}
                </v-icon>
                {{ system.name }}
              </v-list-item-title>
              <v-list-item-subtitle class="d-flex">
                <div class="lighten-5 pa-3 round" :class="system.bgColor">
                  {{ system.welcome }}
                </div>
              </v-list-item-subtitle>
            </v-list-item-content>
          </v-list-item>
          <v-list-item v-for="talk in talks" :key="talk.id">
            <v-list-item-content>
              <v-list-item-title
                class="d-flex align-center"
                :class="
                `${talk.type === 'question' ? 'justify-end ' + user.nameColor + '--text' : system.nameColor + '--text'}`
                "
              >
                {{ talk.type === 'question' ? $store.getters.userInfo.username : '' }}
                <template v-if="talk.type === 'question'">
                  <v-chip v-for="tag in talk.tags" :key="tag" x-small class="ml-2">{{ tag }}</v-chip>
                </template>
                <v-icon
                  :class="talk.type === 'question' ? 'ml-3' : 'mr-3'"
                  :color="talk.type === 'question' ? user.iconColor : system.iconColor"
                >
                  {{ talk.type === 'question' ? user.icon : system.icon }}
                </v-icon>
                {{ talk.type === 'question' ? '' : system.name }}
                <template v-if="talk.type !== 'question'">
                  <v-chip v-for="tag in talk.tags" :key="tag" x-small class="ml-2">{{ tag }}</v-chip>
                </template>
              </v-list-item-title>
              <v-list-item-subtitle class="d-flex" :class="{'justify-end': talk.type === 'question'}">
                <div class="lighten-5 pa-3 round" :class=" talk.type === 'question' ? user.bgColor : system.bgColor">
                  <template v-if="talk.view === 'table'">
                    <v-simple-table fixed-header dense height="350">
                      <template v-slot:default>
                        <thead>
                          <tr>
                            <th v-for="header in talk.content.headers" :key="header" class="text-left">
                              {{header}}
                            </th>
                          </tr>
                        </thead>
                        <tbody>
                          <tr
                            v-for="(body, i) in talk.content.body"
                            :key="i"
                          >
                            <td v-for="header in talk.content.headers" :key="header">{{ body[header] }}</td>
                          </tr>
                        </tbody>
                      </template>
                    </v-simple-table>
                  </template>
                  <template v-else>
                    <div v-for="(content, index) in talk.content" :key="index + content">{{ content }}</div>
                    <!-- {{ talk.content }} -->
                  </template>
                </div>
              </v-list-item-subtitle>
            </v-list-item-content>
          </v-list-item>
          <!-- loading -->
          <v-list-item style="min-height: 10px" v-show="loading">
            <v-list-item-content>
              <v-list-item-title class="d-flex align-center" :class="system.nameColor + '--text'">
                <v-icon class="mr-3" :color="system.iconColor">
                  {{ system.icon }}
                </v-icon>
                <div class="mr-3">{{ system.name }} 搜索中 </div>
                <v-progress-circular
                  size="18"
                  width="2"
                  indeterminate
                  :color="system.iconColor"
                ></v-progress-circular>
              </v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list>
      </div>
    </div>
    <div class="send d-flex align-center justify-center">
      <div class="send-box">
        <v-textarea
          v-model="question"
          dense
          class="send-box-area"
          auto-grow
          label="请输入您想问的内容，按 Ctrl+Enter 换行"
          placeholder="请输入您想问的内容，按 Ctrl+Enter 换行"
          solo
          hide-details
          no-resize
          rows="1"
          @keydown.enter="handleKeyCode($event)"
        >
        </v-textarea>
        <v-btn icon color="primary" class="btn" :disabled="!question" @click="handleSendMsg">
          <v-icon>mdi-send</v-icon>
        </v-btn>
      </div>
    </div>
  </div>
</template>

<script>
import { api } from '@/api/dataGovernance'
export default {
  name: 'knowledge-talk',
  props: {
    // 1 手册探索 2 图表实验室 3 产品知识库 (RAG + Graph) 4 产品知识库 (RAG)
    type: {
      type: Number,
      default: 1
    },
    title: {
      type: String,
      default: '数据探索'
    },
    welcome: {
      type: String,
      default: '您好，我是您的智能助手，有什么问题可以问我哦！'
    }
  },
  data () {
    return {
      // 系统端信息配置
      system: {
        name: '智能助手',
        nameColor: 'indigo',
        icon: 'mdi-face-agent',
        iconColor: 'indigo',
        bgColor: 'indigo',
        welcome: this.welcome
      },
      // 用户端信息配置
      user: {
        name: this.$store.getters.userInfo.username,
        nameColor: 'blue',
        icon: 'mdi-account-circle',
        iconColor: 'blue',
        bgColor: 'blue'
      },
      loading: false,
      talks: [],
      question: '',
      list: [],
      id: 0
    }
  },
  watch: {
    // 长度变化自动滑动至底部
    talks: {
      handler () {
        this.$nextTick(() => {
          this.$refs.box.scrollTo({
            top: this.$refs.box.scrollHeight,
            behavior: 'smooth'
          })
        })
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    handleSendMsg () {
      if (!this.question) {
        return
      }
      switch (this.type) {
        case 2:
          this.getSql()
          break
        case 4:
          this.talkTo(3, true)
          break
        default:
          this.talkTo(this.type)
          break
      }
    },
    handleKeyCode (event) {
      if (event.keyCode === 13) {
        if (!event.ctrlKey) {
          event.preventDefault()
          this.handleSendMsg()
        } else {
          this.question += '\n'
        }
      }
    },
    async getSql () {
      this.loading = true
      this.talks.push({
        id: this.id++,
        type: 'question',
        tags: [],
        content: this.question.split('\n')
      })
      const params = {
        question: this.question
      }
      this.question = ''
      try {
        const { data } = await api.getSql(params)
        this.talks.push({
          id: this.id++,
          type: 'response',
          tags: [],
          content: data.text.split('\n')
        })
        this.getTable(data.id)
      } catch (error) {
        this.$snackbar.error(error)
      } finally {
        this.loading = false
      }
    },
    async getTable (id) {
      this.loading = true
      const params = { id }
      try {
        const { data } = await api.getToTable(params)
        if (data.type === 'error') {
          return
        }
        const _table = JSON.parse(data.df)
        if (!_table.length) {
          return
        }
        // console.log(_table)
        const _headers = Object.keys(_table[0])
        this.talks.push({
          id: this.id++,
          type: 'response',
          tags: [],
          content: {
            headers: _headers,
            body: _table
          },
          view: 'table'
        })
        this.$emit('change', _headers, _table)
      } catch (error) {
        this.$snackbar.error(error)
      } finally {
        this.loading = false
      }
    },
    async talkTo (useType, rag) {
      this.talks.push({
        id: this.id++,
        type: 'question',
        tags: [],
        content: this.question.split('\n')
      })
      const param = {
        question: this.question,
        chat_history: this.list
      }
      this.question = ''
      this.loading = true
      const askApi = useType === 3 ? api.askToUnstructured : api.ask
      try {
        const { data } = await askApi(param)
        this.talks.push({
          id: this.id++,
          type: 'response',
          tags: useType === 3 ? ['RAG + Graph'] : [],
          content: data.response.split('\n')
        })
        // 多获取一个图谱+RAG
        if (rag) {
          const { data: _data } = await api.askToProduct(param)
          this.talks.push({
            id: this.id++,
            type: 'response',
            tags: ['RAG'],
            content: _data.response.split('\n')
          })
        }
      } catch (error) {
        this.$snackbar.error(error)
      } finally {
        this.loading = false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.round {
  border-radius: 5px;
  max-width: 80%;
}
.send {
  // height: 130px;
  // margin: 20px 0;
  padding: 20px;
  &-box {
    width: 100%;
    // max-width: 800px;
    position: relative;
    .btn {
      position: absolute;
      right: 20px;
      bottom: 12px;
    }
    &-area {
      position: relative;
      bottom: 0;
      ::v-deep textarea {
        padding: 15px 70px 15px 0 !important;
        max-height: 300px;
        min-height: 60px;
        overflow: auto;
        margin: 0 !important;
      }
    }
  }
}
</style>
