<script setup>
import { ref, unref, computed, onMounted, onUnmounted } from 'vue';
import { useMessage } from 'naive-ui';
import { BaseButton, RecodeCardItem, TheSubMenu, TheChatView, ChatWelcome, SvgIcon } from '@/components';
import { ChatAsk, ChatAnswer, ChatAgentInput } from '@/components/Chat';
import { getFormatYesterDay } from '@/utils/format';
import { chatApi } from '@/api/chat';
import { helperApi } from '@/api/helper';

import { useInfinite, useScroll, useChat } from '@/composables';

const ANSWER_ID_KEY = '@@id@@';

let controller = new AbortController();

const { recordList, isFetching, onScrolltolower, onReset, } = useInfinite('/front/bigModel/qa/pageList', { module: 2 });
const { scrollRef, scrollToBottom, scrollToBottomIfAtBottom } = useScroll();
const { chatDataSource, addChat, updateChat, clearChat, updateById } = useChat();

const helperList = ref([]);
const message = useMessage();

const switchActive = ref(false);

const isLoading = ref(false);
const inputRef = ref(null);
const recordActive = ref(null);

const activeItem = ref({});

const currenSessionId = ref(null);

const isExistInHistory = computed(() => (recordList.value.findIndex(({ sessionId: sId }) => sId === unref(currenSessionId)) === -1));

// 新建对话
const handleCreateDialog = async () => {
  message.destroyAll();

  inputRef.value.clearFileList();

  if (unref(isLoading)) {
    return message.warning('当前对话生成中');
  }

  if (!unref(chatDataSource).length) {
    return message.info('已切换最新会话');
  }

  inputRef.value.clearInpVal();

  recordActive.value = null;

  currenSessionId.value = null;

  clearChat();
}

// 查询对话详情
const handleChatDetail = async ({ sessionId }) => {
  isLoading.value = false;

  recordActive.value = sessionId;

  inputRef.value.clearInpVal();

  controller.abort();

  const { data } = await chatApi.getAnswerHistoryDetail({ sessionId });

  chatDataSource.value = data.map(item => {
    const uploadFileList = []

    if ( item.question.includes('file:') ) {
      
      const fileInfo = item.question.split("||");
      const fileArr = fileInfo[0].split(":");
      const file = fileArr[1];
      const url = fileInfo[1];
      const suffix = file.substring( file.lastIndexOf('.') + 1 ).toUpperCase();
      const originSuffix = file.substring( file.lastIndexOf('.') );
      const name = file.substring(0, file.lastIndexOf('.'))

      uploadFileList.push({
        name,
        originSuffix,
        suffix,
        url
      })
    }
    return ({ ...item, loading: false, uploadFileList})
  });

  currenSessionId.value = sessionId;

  scrollToBottom();
}

const onRegenerate = async ({ showVal, question, tools, uploadFileList }) => {
  controller = new AbortController();

  const sessionId = unref(currenSessionId);
  let fileQuestionStr = '';

  if ( uploadFileList && uploadFileList.length ) {
    const [ fileItem ] = uploadFileList;
    fileQuestionStr = `file:${fileItem.name + fileItem.originSuffix}||${fileItem.url}||${question}`
  }

  const params = {
    data: {
      sessionId,
      showVal,                        // 展示问题
      question: fileQuestionStr || question,    // 给大模型的问题
      module: 2,
      tools: activeItem.value.tools || tools,
      isStrong: Number(unref(switchActive))
    },
    signal: controller.signal,
    onDownloadProgress: ({ event }) => {
      const xhr = event.target;
      const { responseText } = xhr;
      const [answer] = responseText.split(ANSWER_ID_KEY);

      updateChat({
        sessionId,
        showVal,   
        question,
        answer,
        uploadFileList,
        loading: true,
        delayLoading: false
      })

      scrollToBottomIfAtBottom();
    }
  }

  try {
    const { data } = await chatApi.getChatStream(params);

    const [answer, id] = data.split(ANSWER_ID_KEY);

    updateChat({
      id,
      sessionId,
      showVal,
      question,
      answer,
      uploadFileList,
      loading: false,
      delayLoading: false
    })

    scrollToBottomIfAtBottom();
  }
  catch (error) {
    console.log("取消了请求 - catch", error);
  }
  finally {
    isLoading.value = false;
    onReset();
  }
}
// 提交问题
const handleSubmit = async ({showVal, question, selectedOption, uploadFileList = []}) => {

  if (unref(isExistInHistory)) {
    const { data: sessionId } = await chatApi.getChatSessionTag();
    currenSessionId.value = sessionId;
  }

  isLoading.value = true;

  addChat({
    sessionId: unref(currenSessionId),
    showVal: showVal,
    question,
    answer: '',
    loading: true,
    delayLoading: true,
    uploadFileList
  })

  scrollToBottom();

  setTimeout(() => onRegenerate({ showVal, question, tools: selectedOption?.tools || null,  uploadFileList}), 2 * 1000);
}

// 处理推荐问题
const handleWelcomeRecommend = (item) => {
  activeItem.value = item;
  inputRef.value.inpVal = item.content;
  inputRef.value.handleInpFocus();
}

// 删除历史对话
const handeChatDelete = async (id) => {
  await chatApi.deleteHistory(id);
  onReset();
  clearChat();
  message.success('删除成功');
}

// 返回操作
const handleback = async () => {

  controller?.abort();
  // await chatApi.getStopChatStream(currenSessionId.value);

  inputRef.value.clearInpVal();

  recordActive.value = null;

  currenSessionId.value = null;

  clearChat();
}

onMounted(async () => {
  const { data } = await helperApi.getHelperList();
  helperList.value = getFormatYesterDay(data);
})

onUnmounted(() => {
  controller.abort();
})
</script>
<template>
  <section class="flex items-start h-full">
    <TheSubMenu title="历史记录" @scrollToLower="onScrolltolower" :loading="isFetching">
      <template #top>
        <div class="create-btn px-[11px] pb-[22px]">
          <BaseButton @click="handleCreateDialog" icon-name="tool-add-circle">新建指令</BaseButton>
        </div>
      </template>

      <div class="pr-[4px] text-[#5e5e5e]">
        <RecodeCardItem v-for="item, index in recordList" :key="item.sessionId + index" :title="item.showVal"
          :time="item.createTime" :data-item="item"
          :class="{ 'recode-card-item_active': recordActive === item.sessionId }" @on-click="handleChatDetail"
          @on-delete="handeChatDelete" />
      </div>
    </TheSubMenu>

    <TheChatView ref="scrollRef" :is-back-btn="!!chatDataSource.length" @on-click-back="handleback">
      <div v-show="!chatDataSource.length">
        <ChatWelcome title="您好,我是LibraAI智能助手" :sub-title="[
          'LibarAI智能助手模块提供撰写文章、生成报告等服务',
          '请替换问题中##的内容'
        ]" />
        <div class="grid-container">
          <div class="grid-content">
            <div class="grid-item" v-for="item in helperList" :key="item.id" @click="handleWelcomeRecommend(item)">
              <div class="grid-item-icon space-x-[8px]">
                <img :src="item.banner" alt="" class="w-[24px]">
                <h3 class="grid-item-title">{{ item.title }}</h3>
              </div>
              <div class="text-[#5E5E5E] mt-[8px] text-justify">
                <template v-if="item.content.indexOf('#') !== -1">
                  <span v-for="word, i in item.content.split('#')" :key="word">
                    {{ word }}<i v-if="i !== item.content.split('#').length - 1" class="text-[#2454FF]">#</i>
                  </span>
                </template>
                <template v-else>
                  <p>{{ item.content }}</p>
                </template>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div class="conversation-item" v-if="chatDataSource.length">
        <template v-for="item in chatDataSource" :key="item.id">
          <ChatAsk :content="item.showVal" :sessionId="item.sessionId" :uploadFileList="item.uploadFileList"></ChatAsk>
          <ChatAnswer :id="item.id" :content="item.answer" :loading="item.loading" :delay-loading="item.delayLoading"
            :isSatisfied="item.isSatisfied" @on-click-icon="params => updateById(params)"></ChatAnswer>
        </template>
      </div>

      <template #footer>
        <ChatAgentInput
          :active-item="activeItem"
          ref="inputRef"
          v-model:loading="isLoading"
          v-model:switch="switchActive"
          @on-click="handleSubmit"
          @on-enter="handleSubmit"
        ></ChatAgentInput>
      </template>
    </TheChatView>
  </section>
</template>

<style scoped lang="scss">
.grid-container {
  position: relative;
  padding-bottom: 20px;
  margin-top: 36px;
  overflow: hidden;
  overflow-y: scroll;

  &::-webkit-scrollbar {
    width: 0px;
  }

  .grid-content {
    column-count: 3;
    column-gap: 16px;
    -moz-column-count: 3;
    -webkit-column-count: 3;
    -moz-column-gap: 16px;
    -webkit-column-gap: 16px;

    .grid-item {
      height: auto;
      padding: 16px;
      margin-bottom: 16px;
      border-radius: 10px;
      background-color: #fff;
      -webkit-column-break-inside: avoid;
      break-inside: avoid;
      border: 1px solid #fff;
      cursor: pointer;

      &:hover {
        border: 1px solid #2454FF;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
      }

      .grid-item-icon {
        display: flex;
        align-items: center;
        justify-content: start;

        .grid-item-title {
          font-size: 14px;
          font-weight: 600;
          color: #1A2029;
        }
      }
    }
  }
}
</style>@/api/order