<template>
  <div class="chat-container">
    <div class="chat-list" ref="scrollContainer">
    
      <AiHint v-model="keyWord" @sendMessage="handleSend"></AiHint>
      
      <div
        v-for="(item, index) in messageList"
        :key="index"
        :class="['chat-item', item.from == 'user' ? 'user-message' : 'ai-message']"
      >
        <!-- 头像 -->
        <img :src="item.from == 'user' ? userIcon : aiIcon" class="user-icon" alt="" />
        <!-- 内容 -->
        <div class="message-content">
          <div class="message-time">{{ item.time }}</div>
          <div class="message-text" :id="`box${index}`">
            <!-- 纯文本 -->
            <div class="text-ros">
              <span v-show="item.type == 'text'">{{ item.text }}</span>
              <AddIssue :issueText="item.text" :list="dictList" v-show="item.add"></AddIssue>
            </div>
            <!-- 图表 -->
            <section v-if="ehcatrsType.includes(item.type)">
              <div class="echarts-box" :id="item.type + index"></div>
              <div class="echatrs-theme">
                <div class="theme-title">风格切换：</div>
                <div class="theme-list">
                  <div
                    class="theme-item"
                    @click="handlerTheme(item, themeIndex)"
                    v-for="(themeItem, themeIndex) in echartsTheme"
                    :key="themeIndex"
                    :class="item.chartInstanceActiveIndex == themeIndex ? 'activeTheme' : ''"
                  >
                    {{ themeItem }}
                  </div>
                </div>
              </div>
            </section>
            <!-- 表格 -->
            <AiTable v-if="item.type ==='table' " :obj="item"></AiTable>
            <!-- 思考 -->
            <div v-show="item.from === 'ai' && item.loading" class="ai-loading">
              <span>思考中</span> <n-spin size="small" content-class="spin-class" />
            </div>
            <!-- 免责 -->
            <div class="ai-hint" v-show="item.from === 'ai' && !item.loading">
              <span>注：本回答由AI生成，内容仅供参考</span>
              <div class="upload-text" @click="uploadImage(index)">
                <n-icon size="14">
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    xmlns:xlink="http://www.w3.org/1999/xlink"
                    viewBox="0 0 16 16"
                  >
                    <g fill="none">
                      <path
                        d="M3.5 13h9a.75.75 0 0 1 .102 1.493l-.102.007h-9a.75.75 0 0 1-.102-1.493L3.5 13h9h-9zM7.898 1.007L8 1a.75.75 0 0 1 .743.648l.007.102v7.688l2.255-2.254a.75.75 0 0 1 .977-.072l.084.072a.75.75 0 0 1 .072.977l-.072.084L8.53 11.78a.75.75 0 0 1-.976.073l-.084-.073l-3.536-3.535a.75.75 0 0 1 .977-1.133l.084.072L7.25 9.44V1.75a.75.75 0 0 1 .648-.743L8 1l-.102.007z"
                        fill="currentColor"
                      ></path>
                    </g>
                  </svg>
                </n-icon>
                <span>下载图片</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 搜索 -->
    <n-input
      class="chat-input"
      round
      v-model:value="keyWord"
      type="textarea"
      placeholder="请输入需要统计的数据"
      :autosize="{ minRows: 5 }"
    >
      <template #suffix>
        <div class="chat-suffix">
           <IssueQuey :list="dictList" v-model="keyWord" @sendMessage="handleSend">常用问题</IssueQuey>
          <n-button :loading="loading" size="small" :class="['chat-send']" :bordered="false" @click="handleSend">
          </n-button>
        </div>
      </template>
    </n-input>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { getAiMsg } from '@/api/ai.js'
import moment from 'moment'
import { LineChart, BarChart, PieChart } from './class/index'
import { AiHint, AiTable,AddIssue,IssueQuey } from '../components'
import userIcon from '@/assets/images/ai/user-icon.png'
import aiIcon from '@/assets/images/ai/ai-icon.png'
import { useMessage } from 'naive-ui'
import useMessageRoomStore from '@/store/modules/messageRoom'
import { canvasCut } from '@/utils'
import { historyMessageRoomById,getDict } from '@/api/path'
import { useRoute } from 'vue-router'

const route = useRoute()
const useMessageRoom = useMessageRoomStore()
const messageDialog = useMessage()
//输入框加载
let loading = ref(false)
//搜索关键字
let keyWord = ref('')
//聊天记录list
let messageList = reactive([])
//聊天室容器
const scrollContainer = ref(null)
//聊天记录最后一个索引
let lastIndex = ref(0)
//主题
const echartsTheme = ['简约风', '商务风', '科技风']
let stopWatch = null
let isWatching = ref(false)
const ehcatrsType = ['pie', 'line', 'bar']
let dictList = ref( [])
/**
 * 页面初始完成
 */
onMounted(() => {
  getDictListist()
  startWatching()
  getMessageInfo()
})

/**
 * 字典
 */
const getDictListist =async ()=>{
  const res =await getDict()
  dictList.value = res.data.records

}

/**
 * 获取聊天详情
 */
const getMessageInfo = async () => {
  const id = checkLastPartIsTimestamp(route.path)
  try {
    const res = await historyMessageRoomById(id)
    if (res.code == 200 && res.data) {
      res.data.content = JSON.parse(res.data.content)
      console.log(res.data)
      useMessageRoom.resetList(res.data)
      res.data.content.map((item, index) => {
        item.chartInstanceActiveIndex = 0
        messageList.push(item)
        initEcharts(item, index)
      })
    }
  } catch {
    messageDialog.error('获取聊天室记录失败！')
  }
}

const checkLastPartIsTimestamp = str => {
  // 找到最后一个 / 的位置
  const lastSlashIndex = str.lastIndexOf('/')
  if (lastSlashIndex === -1) {
    return false
  }
  // 截取最后一个 / 后面的值
  const lastPart = str.slice(lastSlashIndex + 1)
  return lastPart
}

/**
 * 问答
 */
const handleSend = async () => {
  if (!keyWord.value.trim() && loading.value ) {
    return
  }
  if (useMessageRoom.messageRoom.content.length >= 35) {
    messageDialog.warning('每个聊天室上限问题为15条！')
    return
  }
  loading.value = true
  //存储用户回答
  setMessageItem({
    from: 'user',
    text: keyWord.value,
    type:'text',
    time: moment().format('YYYY/MM/DD HH:mm:ss'),
    add: true
  })

  //先存储AI回答，作为交互提示，接口响应后再做更新
  setMessageItem(
    {
      from: 'ai',
      text: '',
      time: moment().format('YYYY/MM/DD HH:mm:ss'),
      loading: true, //ai思考中
      chartInstanceItem: null,
      chartInstanceActiveIndex: 0,
      type:'text',
      xData: [],
      yData: []
    },
    false
  )
  try {
    const res = await getAiMsg({ prompt: keyWord.value })

    // 更新
    updataMessageItem({
      from: 'ai',
      text: res.data,
      time: moment().format('YYYY/MM/DD HH:mm:ss'),
      loading: false, //ai思考中
      chartInstanceItem: null,
      chartInstanceActiveIndex: 0,
      type: res.type,
      xData: res.xData,
      data: res.data,
      title: res.title,
      unit: res.unit
    })

  
    nextTick(() => {
     
      const itemData = messageList[lastIndex.value]
      //饼图
      if (res.type === 'pie') {
        itemData.chartInstanceItem = new PieChart(`${res.type}${lastIndex.value}`, {
          title: res.title,
          unit: res.unit,
          data: res.data
        })
      } else if (res.type === 'bar') {
        itemData.chartInstanceItem = new BarChart(`${res.type}${lastIndex.value}`, {
          title: res.title,
          unit: res.unit,
          xData: res.xData,
          data: res.data
        })
      } else if (res.type === 'line') {
        itemData.chartInstanceItem = new LineChart(`${res.type}${lastIndex.value}`, {
          title: res.title,
          unit: res.unit,
          xData: res.xData,
          data: res.data
        })
      }
    })
  } catch {
    updataMessageItem({
      from: 'ai',
      type: 'text',
      text: '服务器繁忙，请稍后再试。',
      time: moment().format('YYYY/MM/DD HH:mm:ss'),
      loading: false
    })
  }
}

/**
 * 同意渲染图表
 */
const initEcharts = (item, index) => {
  nextTick(() => {
    //饼图
    if (item.type === 'pie') {
      item.chartInstanceItem = new PieChart(`${item.type}${index}`, {
        title: item.title,
          unit: item.unit,
          data: item.data
      })
    } else if (item.type === 'bar') {
      item.chartInstanceItem = new BarChart(`${item.type}${index}`, {
        title: item.title,
        unit: item.unit,
        xData: item.xData,
        data: item.data
      })
    } else if (item.type === 'line') {
      item.chartInstanceItem = new LineChart(`${item.type}${index}`, {
        title: item.title,
        unit: item.unit,
        xData: item.xData,
        data: item.data
      })
    }
  })
}
/**
 * 存储聊天室数据
 * @param obj
 */

const setMessageItem = (obj, set = true) => {
  messageList.push(obj)
  lastIndex.value = messageList.length - 1
  if (set) {
    useMessageRoom.setMessage(obj)
  }
}

/**
 * ai回答后更新对应数据
 * @param data
 */
const updataMessageItem = data => {
  messageList[lastIndex.value] = data
  keyWord.value = ''
  loading.value = false
  useMessageRoom.setMessage(data)
  // useMessageRoom.setMessage({
  //   from: data.from,
  //   text: data.text,
  //   type: data.type,
  //   loading: false, //ai思考中
  //   time: data.time,
  //   chartInstanceItem: data.chartInstanceItem,
  //   chartInstanceActiveIndex: 0,
  //   xData: data.xData,
  //   yData: data.yData,
  //   title: data.title,
  //   unit: data.unit
  // })
}

/**
 * 图表切换主题
 * @param index
 */
const handlerTheme = (item, index) => {
  if (isWatching.value) {
    pauseWatching()
    isWatching.value = false
    console.log('暂停')
  }
  item.chartInstanceActiveIndex = index
  item.chartInstanceItem.changeColorStyle(index)

  setTimeout(() => {
    startWatching()
    console.log('监听')
  }, 5000)
}

/**
 * 下载AI回答为图片
 */
const uploadImage = index => {
  // 导出图片
  const range = document.getElementById(`box${index}`)

  // 隐藏边距线
  if (!range) {
    window['$message'].error('下载失败！')
    return
  }

  canvasCut(range)
}

// 聊天室自动滚动条下拉

const startWatching = () => {
  stopWatch = watch(messageList, newVal => {
    nextTick(() => {
      if (scrollContainer.value) {
        scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight
      }
    })
  },{deep:true})
  isWatching.value = true
}

const pauseWatching = () => {
  if (stopWatch) {
    stopWatch() // 调用停止函数
    stopWatch = null
  }
}
onUnmounted(() => {
  //清除
  messageList.forEach(instance => {
    if (ehcatrsType.includes( instance.type) && instance.type) {
      instance.chartInstanceItem.dispose()
    }
  })
})
</script>

<style lang="scss" scoped>
/* 设置滚动条整体样式 */
::-webkit-scrollbar {
  width: 0px;
}
</style>
