<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' ? formatName(baseInfo?.name ?? baseInfo?.phone) : '' }}
                <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>
                  </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 setup>
import { ref, watch, nextTick } from 'vue'
import { api } from '@/api/dataGovernance'
import { formatName } from '@/utils/getText'
import Snackbar from '@/plugins/snackbar'

const props = defineProps({
  // 1 手册探索 2 图表实验室 3 产品知识库 (RAG + Graph) 4 产品知识库 (RAG)
  type: {
    type: Number,
    default: 1
  },
  title: {
    type: String,
    default: '数据探索'
  },
  welcome: {
    type: String,
    default: '您好，我是您的智能助手，有什么问题可以问我哦！'
  }
})

// 企业基本信息
const baseInfo = ref(JSON.parse(localStorage.getItem('entBaseInfo')) || {})

const box = ref(null)
const loading = ref(false)
const talks = ref([])
const question = ref('')
const id = ref(0)

// 系统端信息配置
const system = ref({
  name: '智能助手',
  nameColor: '#00B760',
  icon: 'mdi-face-agent',
  iconColor: '#00B760',
  bgColor: '#00B760',
  welcome: props.welcome
})

// 用户端信息配置
const user = ref({
  name: formatName(baseInfo.value?.name ?? baseInfo.value?.phone),
  nameColor: 'blue',
  icon: 'mdi-account-circle',
  iconColor: '#00B760',
  bgColor: '#00B760'
})

// 监听talks变化，自动滚动到底部
watch(talks, () => {
  nextTick(() => {
    box.value.scrollTo({
      top: box.value.scrollHeight,
      behavior: 'smooth'
    })
  })
}, { deep: true, immediate: true })

const handleSendMsg = () => {
  if (!question.value) {
    return
  }
  switch (props.type) {
    case 2:
      getSql()
      break
    case 4:
      talkTo(3, true)
      break
    default:
      talkTo(props.type)
      break
  }
}

const handleKeyCode = (event) => {
  if (event.keyCode === 13) {
    if (!event.ctrlKey) {
      event.preventDefault()
      handleSendMsg()
    } else {
      question.value += '\n'
    }
  }
}

const getSql = async () => {
  loading.value = true
  talks.value.push({
    id: id.value++,
    type: 'question',
    tags: [],
    content: question.value.split('\n')
  })
  const params = {
    question: question.value
  }
  question.value = ''
  try {
    const { data } = await api.getSql(params)
    talks.value.push({
      id: id.value++,
      type: 'response',
      tags: [],
      content: data.text.split('\n')
    })
    getTable(data.id)
  } catch (error) {
    Snackbar.error(error)
  } finally {
    loading.value = false
  }
}

const getTable = async (id) => {
  loading.value = true
  const params = { id }
  try {
    const { data } = await api.getToTable(params)
    if (data.type === 'error') {
      return
    }
    const _table = JSON.parse(data.df)
    talks.value.push({
      id: id.value++,
      type: 'response',
      tags: [],
      view: 'table',
      content: _table
    })
  } catch (error) {
    Snackbar.error(error)
  } finally {
    loading.value = false
  }
}

const talkTo = async (type, isRag = false) => {
  loading.value = true
  talks.value.push({
    id: id.value++,
    type: 'question',
    tags: [],
    content: question.value.split('\n')
  })
  const params = {
    question: question.value,
    type,
    isRag
  }
  question.value = ''
  try {
    const { data } = await api.talkTo(params)
    talks.value.push({
      id: id.value++,
      type: 'response',
      tags: data.tags || [],
      content: data.text.split('\n')
    })
  } catch (error) {
    Snackbar.error(error)
  } finally {
    loading.value = false
  }
}
</script>

<style lang="scss" scoped>
.send {
  padding: 10px;
  border-top: 1px solid #e0e0e0;
  .send-box {
    width: 100%;
    display: flex;
    align-items: center;
    .send-box-area {
      flex: 1;
      margin-right: 10px;
    }
    .btn {
      flex-shrink: 0;
    }
  }
}
.round {
  border-radius: 8px;
}
</style>
