<template>
  <div class="chat-container">
    <div class="chat-list" ref="scrollContainer">
      <!-- <div>
        <div class="echarts-box" id="barEcharts"></div>
        <div class="echatrs-theme">
          <div class="theme-title">风格切换：</div>
          <div class="theme-list">
            <div class="theme-item" @click="handlerTheme(index)" v-for="(item, index) in echartsTheme" :key="index">
              {{ item }}
            </div>
          </div>
        </div>
      </div> -->

      <AiHint></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>{{ item.text }}</span>
              <div v-show="item.add">
                <n-tooltip placement="bottom" trigger="hover">
                  <template #trigger>
                    <n-icon size="14" style="cursor: pointer">
                      <svg
                        xmlns="http://www.w3.org/2000/svg"
                        xmlns:xlink="http://www.w3.org/1999/xlink"
                        viewBox="0 0 12 12"
                      >
                        <g fill="none">
                          <path
                            d="M6.5 1.75a.75.75 0 0 0-1.5 0V5H1.75a.75.75 0 0 0 0 1.5H5v3.25a.75.75 0 0 0 1.5 0V6.5h3.25a.75.75 0 0 0 0-1.5H6.5V1.75z"
                            fill="currentColor"
                          ></path>
                        </g>
                      </svg>
                    </n-icon>
                  </template>
                  <span> 添加为常用问题 </span>
                </n-tooltip>
              </div>
            </div>
            <!-- 图表 -->
            <section v-if="item.chartType">
              <div class="echarts-box" :id="item.chartType + 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>

            <!-- 思考 -->
            <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.text || item.chartType)">
              <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">
          <span>常用问题</span>
          <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 } 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 } 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

/**
 * 页面初始完成
 */
onMounted(() => {
  startWatching()

  getMessageInfo()
})

/**
 * 获取聊天详情
 */
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)
      useMessageRoom.resetList(res.data)
      res.data.content.map((item, index) => {
        messageList.push(item)
        initEcharts(item, index)
      })
      console.log(res.data)
    }
  } 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()) {
    messageDialog.warning('请先输入需要统计的数据！')
    return
  }
  if (useMessageRoom.messageRoom.content.length >= 35) {
    messageDialog.warning('每个聊天室上限问题为15条！')
    return
  }
  loading.value = true
  //存储用户回答
  setMessageItem({
    from: 'user',
    text: keyWord.value,
    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,
      chartType: null,
      xData: [],
      yData: []
    },
    false
  )
  try {
    const res = await getAiMsg({ prompt: keyWord.value })
    if (res.type) {
      // 更新
      updataMessageItem({
        from: 'ai',
        text: '',
        time: moment().format('YYYY/MM/DD HH:mm:ss'),
        loading: false, //ai思考中
        chartInstanceItem: null,
        chartInstanceActiveIndex: 0,
        chartType: res.chartType,
        xData: res.xData,
        yData: res.yData,
        title: res.title,
        unit: res.unit
      })

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

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

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

/**
 * ai回答后更新对应数据
 * @param data
 */
const updataMessageItem = data => {
  messageList[lastIndex.value] = data
  keyWord.value = ''
  loading.value = false
  useMessageRoom.setMessage({
    from: data.from,
    text: data.text,
    chartType: data.chartType,
    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) => {
  pauseWatching()
  item.chartInstanceActiveIndex = index
  item.chartInstanceItem.changeColorStyle(index)
  setTimeout(() => {
    startWatching()
  }, 1000)
}

/**
 * 下载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
      }
    })
  })
}

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

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