<!-- Chat.vue -->
<template>
  <div class="chat-container">
    <div v-if="!messages.length" class="message-list">
      <pageMask />
    </div>
    <!-- 消息列表 -->
    <div class="message-list" v-else>
      <el-scrollbar ref="scrollbar" @scroll="handleScroll">
        <div class="messages">
          <div v-for="(message, index) in messages" :key="index"
               :class="['message-item', message.isSelf ? 'self' : 'other']">
            <el-avatar :size="32" :src="message.avatar" />
            <div class="message-content">
              <div class="content" v-if="!message.isSelf" :class="{ 'loading-content': message.content === '' }">
                <formTable v-if="message.type === 'form'" :content="message.rawContent" />
                <span v-else v-html="message.content"></span>
                <span class="loading-indicator" v-if="sendLoading && index === messages.length - 1">
                  <span class="dot"></span>
                  <span class="dot"></span>
                  <span class="dot"></span>
                </span>
              </div>
              <document v-else-if="message.type === 'document' && message.isSelf" :content="message.content"
                        :rawContent="message.rawContent" />
              <div v-else class="content">
                <span v-if="message.type === ''">{{ message.content }}</span>
                <span class="loading-indicator" v-if="sendLoading && index === messages.length - 1">
                <span class="dot"></span>
                <span class="dot"></span>
                <span class="dot"></span>
              </span>
              </div>
              <div class="timestamp ">{{ moment(message.timestamp).format('MM-DD HH:mm') }}
                <span v-if="message.add" style="cursor: pointer;" @click="handleInput">填充</span>
              </div>
            </div>
          </div>
        </div>
      </el-scrollbar>
      <ScrollToBottom :target="scrollbar" ref="scrollToBottomRef" />
    </div>

    <Tools @read-click="readClick"
           @upload-file="handleUpload"
           @handle-capture="handleCapture"
           @his-records="hisRecords"
           @add-new-dialogue="addNewDialogue"
           @handle-current-change="handleCurrentChange"
           @handel-intelligent-filling-click="handelIntelligentFillingClick" />

    <div>
      <!-- 输入区域 -->
      <div class="input-area">
        <div v-show="isShowPage" style="border-bottom: 1px solid #F0F0F0;">
          <div class="card_list">
            <div v-for="(v,i) in pageInfoList" :key="i"
                 :class="`card-content ${pageInfoList.length > 1 ? 'card_width' : ''}`">
              <img :src="v?.favIconUrl" style="width: 24px;display: block" />
              <div class="title-wrapper">
                <span class="els title-scroller">{{ v?.title }}</span>
                <span class="els url-scroller">{{ v?.url }}</span>
              </div>
              <el-icon class="closeIcon" size="16px" color="#909399" @click="deletePageInfo(i)">
                <CircleClose />
              </el-icon>
            </div>
          </div>

          <div v-show="type !== FunctionList.Intelligent_Form_filling" class="card-btn">
            <el-tooltip content="总结当前页面" placement="top">
              <el-button round @click="handleSummary">总结</el-button>
            </el-tooltip>
          </div>
        </div>

        <el-input ref="textareaRef" v-model="inputMessage" type="textarea" :rows="3" placeholder="输入消息..."
                  @keyup.enter="handleAsk" />
        <div class="chat_area_op">
          <el-button
            :style="`background-color:${inputMessage.trim() ? '#4d6bfe' : '#d6dee8'};border-color:${inputMessage.trim() ? '#4d6bfe' : '#d6dee8'}`"
            v-if="inputMessage.trim() || !sendLoading" type="primary" circle @click="handleAsk"
            :disabled="!inputMessage.trim() || sendLoading">
            <svg-icon icon-class="send" color="#000000" />
          </el-button>
          <el-button style="background-color:#ffffff;border:2px solid rgb(134 143 153);" v-else circle
                     @click="handleStopAsk">
            <svg-icon icon-class="stop" color="red" />
          </el-button>

        </div>
      </div>

    </div>


    <!--  历史记录  -->
    <historyComponent :msgUuid="msgUuid" ref="historyComponentRef" @currentData="(e)=>handleCurrentData(e)" />
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, inject, useTemplateRef, reactive } from 'vue'
import { ElScrollbar, ElAvatar, ElInput, ElButton } from 'element-plus'
import moment from 'moment'
import { cloneDeep } from 'lodash'
import fileLogo from '@/assets/svg/file.svg'
import {
  buildExcelUnderstandingPrompt,
  getSummaryPrompt,
  getFileContent,
  buildObjPrompt,
  modelFileUpload,
  controllerList
} from '@/entrypoints/sidepanel/utils/ai-service.js'
import { storeToRefs } from 'pinia'
import { ElMessage } from 'element-plus'
import { useMsg } from '@/entrypoints/sidepanel/hook/useMsg.ts'
import Tools from '@/entrypoints/sidepanel/component/tools.vue'
import historyComponent from '@/entrypoints/sidepanel/component/historyComponent.vue'
import document from '@/entrypoints/sidepanel/component/document.vue'
import pageMask from '@/entrypoints/sidepanel/component/pageMask.vue'
import ScrollToBottom from '@/entrypoints/sidepanel/component/ScrollToBottom.vue'
import formTable from '@/entrypoints/sidepanel/component/formTable.vue'

import { mockData, startMsg, mockData2, options, FunctionList } from '@/entrypoints/sidepanel/mock'
import { useAutoResizeTextarea } from '@/entrypoints/sidepanel/hook/useAutoResizeTextarea.ts'
import { getPageInfo, getXlsxValue, handleInput } from './utils/index.js'
import { useMsgStore } from '@/store/modules/msg.ts'

// 滚动条引用
const scrollbar = ref(null)
const scrollToBottomRef = ref(null)
const xlsxData = ref({})
const isShowPage = ref(false)
const tareRef = useTemplateRef('textareaRef')
const drawerRef = useTemplateRef('historyComponentRef')
// 获取父组件提供的 Hook 实例
const { registerStore, useStore } = inject('indexedDBHook')
const msgStore = useMsgStore()
const { pageInfoList, messages, msgUuid, AIModel } = storeToRefs(useMsgStore())
const formInfo = ref('')

const {
  taklToHtml,
  sendLoading,
  type,
  streamRes,
  getFormKeyAndValue,
  requestFlowFn,
  fetchRes
} = useMsg(scrollbar)
const inputMessage = ref('')
const pageInfo = ref('')


function handleStopAsk() {
  if (type.value === FunctionList.Intelligent_Form_filling) {
    inputMessage.value = ''
    pageInfoList.value = []
    isShowPage.value = false
    taklToHtml.value = false
    type.value = FunctionList.File_Operation
  }
  controllerList.value[0].abort()
  controllerList.value = []
  sendLoading.value = false
}

function handleScroll({ scrollTop }) {
  // scrollTop 滚动条的位置
  const { wrapRef } = scrollbar.value
  const { scrollHeight, clientHeight } = wrapRef
  scrollToBottomRef.value.showButton = scrollHeight - scrollTop - clientHeight >= 350
}

/**
 * @param {string} msg
 * @param {string} raw
 * @param {string} type 发送的类型 document 、text
 * **/
async function addMessage(msg, raw, type) {
  console.log(msg);
  
  // 添加indexDB Store配置
  if (msgUuid.value === '') {
    msgUuid.value = 'D' + Date.now().toString()
    await registerStore({
      name: msgUuid.value,
      keyPath: 'id'
    })
  }
  const newMessage = reactive({
    id: messages.value.length + 1,
    type: type || '',
    username: '我',
    rawContent: raw ?? msg,
    content: msg,
    timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
    isSelf: true,
    avatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
    addToHistory: !taklToHtml.value
  })
  if (type === 'document') {
    newMessage.content = msg
    newMessage.rawContent = raw
  }
  if (!msg) return

  messages.value.push(newMessage)
  useStore(msgUuid.value).add(cloneDeep(newMessage))
  await nextTick(() => {
    scrollbar.value?.setScrollTop(99999)
  })
  return newMessage
}

const handleSummary = async () => {
  let params = []
  if (AIModel.value.file === true) {
    pageInfoList.value.forEach((pageInfo) => {
      params.push({ role: 'system', content: `fileid://${pageInfo.fileId}` })
    })
    params.push({
      role: 'user', content: `
    请根据这几个文件的文本内容综合分析总结
    要求：
    1.抽取文件的文本内容
    2.对每个文件中的文本内容进行分别总结
    3.对步骤二总结的内容进行综合总结`
    })
  } else {
    let tempStr = ''
    pageInfoList.value.forEach((pageInfo, index) => {
      pageInfo.handleText = getSummaryPrompt(pageInfo.content)
      tempStr += `第${index + 1}段：${pageInfo.handleText}\n`
    })
    params = [{
      role: 'user',
      content: `请根据以下这几段内容综合总结出结果：
      ${tempStr}要求：
      1. 用简洁清晰的语言提取所有的核心要点
      2. 保持客观中立的语气
      3. 按重要性排序
      4. 返回内容做好换行，以及展示样式
      5. 请以"以下是对该文件内容的总结："开头，然后用要点的形式列出主要内容。
      6. 对这几段内容进行综合分析及联想`
    }]
  }
  await addMessage(pageInfoList.value, '总结', 'document')
  if (requestFlowFn) {
    isShowPage.value = false
    taklToHtml.value = false
    pageInfoList.value = []
    const res = await requestFlowFn(params)
  }
}

async function handelIntelligentFillingClick() {
  isShowPage.value = true
  taklToHtml.value = true
  const tempPageInfo = await getPageInfo()
  pageInfo.value = tempPageInfo
  pageInfoList.value = [tempPageInfo]
  inputMessage.value = '/智能填表 '
  type.value = FunctionList.Intelligent_Form_filling
}

function handleCurrentChange(e) {
  options.forEach((item) => {
    item.options.forEach((item2) => {
      if (item2.value === e) {
        msgStore.updateAIModel(item2)
      }
    })
  })
  if (AIModel.value.file === true) {
    isShowPage.value = false
    taklToHtml.value = false
    pageInfoList.value = []
  }
}

function handleCurrentData(e) {
  drawerRef.value.drawer = false
  if (!e) {
    addNewDialogue()
    return
  }
  // 添加indexDB Store配置
  msgUuid.value = e
  useStore(e).getAll().then((res) => {
    messages.value = res
    nextTick(() => {
      scrollbar.value?.setScrollTop(99999)
    })
  })
}

async function readClick() {
  if (type.value === FunctionList.Intelligent_Form_filling) {
    pageInfoList.value = []
    type.value = FunctionList.File_Operation
  }
  isShowPage.value = true
  taklToHtml.value = true
  if (pageInfoList.value.length >= Number(import.meta.env.VITE_MAX_FILE_NUMBER)) {
    ElMessage.warning(`最多添加${import.meta.env.VITE_MAX_FILE_NUMBER}个文件`)
    return
  }
  const tempPageInfo = await getPageInfo()
  if (AIModel.value.file === true) {
    const blob = new Blob([tempPageInfo.content.mainContent], { type: 'text/plain' })
    const file = new File([blob], tempPageInfo.title + '.txt', { type: 'text/plain' })
    tempPageInfo.fileId = await modelFileUpload(file)
  }
  pageInfoList.value.unshift(tempPageInfo)
}

function deletePageInfo(i) {
  pageInfoList.value.splice(i, 1)
  if (pageInfoList.value.length === 0) {
    isShowPage.value = false
    taklToHtml.value = false
    if (type.value === FunctionList.Intelligent_Form_filling) inputMessage.value = ''
    type.value = FunctionList.File_Operation
  }
}

function addNewDialogue() {
  if (msgUuid.value === '') {
    ElMessage.warning('已经是新对话')
    return
  }
  isShowPage.value = false
  taklToHtml.value = false
  messages.value = []
  pageInfoList.value = []
  msgUuid.value = ''
}

async function handleAsk() {
  const str = inputMessage.value.trim()
  inputMessage.value = ''
  if (sendLoading.value) return
  addMessage(str)
  if (type.value === FunctionList.Intelligent_Form_filling) {
    const res = await fetchRes(str)
    console.log(res);

    if (res.status === 'ok') {
      formInfo.value = res.data
      console.log(res,55558)
    } else {
      type.value = FunctionList.File_Operation
      isShowPage.value = false
      taklToHtml.value = false
      pageInfoList.value = []
    }
  } else streamRes(taklToHtml.value)
  inputMessage.value = ''
}

function handleCapture() {
  ElMessage({
    message: '开发中...',
    grouping: true,
    showClose: true
  })
}

function hisRecords() {
  drawerRef.value.drawer = true
}

const handleUpload = async (file) => {
  if (AIModel.value.file === true) {
    const id = await modelFileUpload(file)
    pageInfoList.value.unshift({
      fileId: id,
      title: file.name,
      url: 'File',
      favIconUrl: fileLogo
    })
    isShowPage.value = true
    taklToHtml.value = true
    return
  }
  if (type.value === FunctionList.Intelligent_Form_filling) {
    const fileExtension = file.name.split('.').pop().toLowerCase()
    if (fileExtension === 'xlsx') {
      const readData = await getXlsxValue(file)
      readData[0].forEach((header, i) => {
        // if (!xlsxData.value[header]) xlsxData.value[header] = []
        xlsxData.value[header] = readData[1][i]
      })
      addMessage(`已上传文件：${file.name}`, buildExcelUnderstandingPrompt(readData[0], file?.name, formInfo.value))
      const {rawContent,status} = await streamRes()
    if (status === 'ok') {
        let form = []
      if (rawContent.includes('json')) form = JSON.parse(rawContent.split('json')[1].split('```')[0])
      else form = JSON.parse(rawContent)
      handleInput(xlsxData.value, form)
    }
    } else {
     try {
       const { data, msg } = await getFileValue(file)
       const res2 = await getFormKeyAndValue(data, formInfo.value)
       xlsxData.value = res2.data
       msg.rawContent = buildObjPrompt(res2.data, formInfo.value)
       console.log(msg.rawContent);
       console.log(messages);
       
       const { rawContent, status } = await streamRes()
       console.log(22555);
       
       if (status === 'ok') {
         let form = []
         if (rawContent.includes('json')) form = JSON.parse(rawContent.split('json')[1].split('```')[0])
         else form = JSON.parse(rawContent)
         handleInput(xlsxData.value, form)
       }
     } catch (error) {
       msg.content = '文件解析出错'
     } finally {
      sendLoading.value = false
     }
    }
    type.value = FunctionList.File_Operation
    isShowPage.value = false
    taklToHtml.value = false
    pageInfoList.value = []
    return
  }
  if (type.value === FunctionList.File_Operation) {
    let formData = new FormData()
    formData.append('file', file)
    const res = await getFileContent(formData)
    pageInfoList.value.unshift({
      title: file.name,
      url: 'File',
      favIconUrl: fileLogo,
      content: {
        mainContent: res.data
      }
    })
    isShowPage.value = true
  }
}

async function getFileValue(file) {
  const msg = await addMessage(`文件上传中`)
  console.log(msg,messages);
  
  sendLoading.value = true
  let formData = new FormData()
  formData.append('file', file)
  const res = await getFileContent(formData)
  console.log(res,5555);
  
  sendLoading.value = false
  msg.content = `已上传文件：${file.name}`
  console.log(msg.content);
  
  msg.rawContent = res.data
  return {
    data: res.data,
    msg
  }
}

// 组件挂载时滚动到底部
onMounted(() => {
  msgStore.updateAIModel(options[0].options[0])
  useAutoResizeTextarea(tareRef, inputMessage)
  chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.type === 'TO_SIDE_PANEL_PAGE_INFO') {
      pageInfo.value = message.data
      // 转发到 content.js
      chrome.tabs.sendMessage(sender.tab.id, {
        type: 'TO_CONTENT_SCRIPT',
        data: message.data
      })
    }
    if (message.type === 'TO_SIDE_PANEL_PAGE_CHANGE') {
      pageInfo.value = message.data
    }
  })

  nextTick(() => {
    scrollbar.value?.setScrollTop(99999)
  })
})
</script>

<style lang="scss" scoped>
@use '@/entrypoints/sidepanel/css/chat.scss';
</style>
