<script setup>
import { ref, unref, computed, onMounted, onUnmounted } from 'vue';
import { useMessage } from 'naive-ui';
import { useChatStore } from '@/stores/modules/chatStore';
import { BaseButton, RecodeCardItem, TheSubMenu, TheChatView, ChatWelcome } from '@/components';
import { ChatAsk, ChatAnswer, ChatAgentInput } from '@/components/Chat';
import { chatApi } from '@/api/chat';

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

const ANSWER_ID_KEY = '@@id@@';

let controller = new AbortController();

const chatStore = useChatStore();

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

const message = useMessage();

const switchActive = ref(false);
const activeItem = ref({});

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

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();

  currenSessionId.value = null;

  recordActive.value = null;

  clearChat();
}

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

  recordActive.value = sessionId;

  controller.abort();
  inputRef.value.clearInpVal();

  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, realQuestion, 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: showVal,
      question: realQuestion || fileQuestionStr || question,
      module: 0,
      modelType: Number(unref(switchActive)),
      isStrong: Number(unref(switchActive)),
      tools,
      prompt: null
      // TODO: 后续大概率需要删除
      // topP: 0.9,
      // temperature: 0.7
    },
    signal: controller.signal,
    onDownloadProgress: ({ event }) => {
      const xhr = event.target;
      const { responseText } = xhr;
      const [ answer ] = responseText.split(ANSWER_ID_KEY);

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

      scrollToBottomIfAtBottom();
    }
  }

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

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

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

    scrollToBottomIfAtBottom();
  }
  catch (error) {
    console.log("取消了请求 - catch", error);
  }
  finally {
    isLoading.value = false;
    onReset();
  }
}
// 提交问题
const handleSubmit = async ({ showVal, question, selectedOption, realQuestion = '', uploadFileList = []}) => {
  // 用于模拟 - 内容生成前置等待状态
  if (unref(isExistInHistory)) {
    const { data: sessionId } = await chatApi.getChatSessionTag();
    currenSessionId.value = sessionId;
  }

  isLoading.value = true;

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

  scrollToBottom();

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

// 处理推荐问题
const handleWelcomeRecommend = ({ question, realQuestion }) => {
  handleSubmit({showVal: question, question, realQuestion});
}

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

// 停止问题生成
const onStopChatStream  = async ({ sessionId }) => {
  await chatApi.getStopChatStream(sessionId);
  return message.warning('已停止对话生成');
}

// 重新生成问题
const onChatResetStream = (item) => {
  const { question, uploadFileList, showVal } = item;
  console.log(item);
  handleSubmit({showVal, question, uploadFileList});
}

onMounted(() => {
  const question = chatStore.chatQuestion;
  if (Object.keys(question).length) {
    handleWelcomeRecommend(chatStore.chatQuestion);
    chatStore.clearChatQuestion();
  }
})

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">
      <ChatWelcome title="您好,我是LibraAI专家问答" card-title="您可以试着问我：" :sub-title="[
        '期待与您一同规划和完成未来的工作。有任何重点或需讨论的事项，随时告诉我'
      ]" :card-content="recommendList" v-if="!chatDataSource.length" @on-click="handleWelcomeRecommend" />

      <div class="conversation-item" v-if="chatDataSource.length">
        <template v-for="item, index 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"
            :isVisibleResetBtn="chatDataSource.length - 1 === index"
            isVisibleStopBtn
            @on-click-stop="onStopChatStream(item)"
            @on-click-icon="params => updateById(params)"
            @on-click-reset="onChatResetStream(item)"
           >
          </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>