<script setup lang="ts">
import { ref, useTemplateRef, watch } from 'vue'
import AgentAbout from './components/agent-about.vue'
import FooterOperation from './components/footer-operation.vue'
import HistoryMenuSidebar from './components/history-menu-sidebar.vue'
import MessageList from './components/message-list.vue'
import type { AgentApplicationRecordItem, MessageItemInterface } from './types'
import { fetchCreateSessionId, fetchMessageRecordList } from '@/apis/home-agent'
import type { ValueOf } from 'type-fest'
import { useElementSize } from '@vueuse/core'
import { debounce } from 'lodash-es'
import { nanoid } from 'nanoid'
import { useI18n } from 'vue-i18n'

const { t } = useI18n()

const homeContainerRef = useTemplateRef<HTMLDivElement>('homeContainerRef')
const messageListRef = useTemplateRef<InstanceType<typeof MessageList>>('messageListRef')
const historyMenuSidebarRef = useTemplateRef<InstanceType<typeof HistoryMenuSidebar>>('historyMenuSidebarRef')
const footerOperationRef = useTemplateRef<InstanceType<typeof FooterOperation>>('footerOperationRef')

const { width: homeContainerWidth } = useElementSize(homeContainerRef)

const isShowHistoryMenu = ref(true)

const currentAgentApplication = ref<AgentApplicationRecordItem>({
  agentId: '',
  agentTitle: '',
  agentAvatar: '',
  agentDesc: '',
  creator: '',
  publishedTime: '',
  points: 0,
  isDocumentParsing: 'N',
  unitIds: [],
})
const currentSessionId = ref('')

const questionContent = ref('')

const messageList = ref(new Map<string, MessageItemInterface>())
const isAgentResponding = ref(false)
const isShowMessageList = ref(false)
const isAgentInitLoading = ref(true)
const currentFetchEventSourceController = ref<AbortController | null>(null)

/* 测试数据 */
/* setTimeout(() => {
  messageList.value.set('1', {
    role: 'assistant',
    agentId: 'b058f1baedd04af983ca00775368bb8c',
    content: '请推荐一些适合初学者的编程学习资源。',
    timestamp: 1726654820427,
    isAnswerLoading: false,
    avatar: 'http://localhost:8848/fe/src/assets/images/home/agent-avatar.png',
    name: '我是作者',
    reasoningContent: '1324',
    imageUrl: '',
    pluginName: '',
    smartFormInfo: {
      type: 'BusinessTripForm',
      isDisabled: false,
      params:
        '{"purpose":"Training","place":"香港","departureDate":"returnDate","accommodationCost":"11","departureDate":"2025-05-10 15:00:00","advancePaymentAmount":"11","totalBudget":"11"}',
    },
  })
}, 60) */

const editorDrawerConfig = ref({
  isShow: false,
  content: '',
})

const homeContainerWidthWatchDebounce = debounce((newWidth) => {
  if (newWidth <= 1120) {
    isShowHistoryMenu.value = false
  } else if (newWidth >= 1320) {
    isShowHistoryMenu.value = true
  }
}, 300)

watch(homeContainerWidth, homeContainerWidthWatchDebounce)

watch(
  () => messageList.value.size,
  (newSize) => {
    if (newSize > 0) {
      setTimeout(() => {
        isShowMessageList.value = true
      }, 400)
    } else if (newSize === 0 && isShowMessageList.value) {
      setTimeout(() => {
        isShowMessageList.value = false
      }, 400)
    }
  },
)
;(function () {
  createSessionId()
})()

function createSessionId() {
  fetchCreateSessionId<string>().then((res) => {
    currentSessionId.value = res.data

    isAgentInitLoading.value = false
  })
}

function onCreateNewSession() {
  if (messageList.value.size === 0) {
    return
  }

  createSessionId()

  messageList.value.clear()
}

function messageListScrollToBottom() {
  if (messageListRef.value) {
    messageListRef.value.scrollToBottom()
  }
}

function onAddMessageItem(messageId: string, messageItem: MessageItemInterface) {
  messageList.value.set(messageId, messageItem)
}

function onUpdateSpecifyMessageItem(messageId: string, newMessageItem: Partial<MessageItemInterface>) {
  const currentMessageItemInfo = messageList.value.get(messageId)

  if (currentMessageItemInfo) {
    const updatePropertyLength = Object.keys(newMessageItem).length

    if (updatePropertyLength > 4) {
      messageList.value.set(messageId, Object.assign({}, currentMessageItemInfo, newMessageItem))
      return
    }

    Object.entries<ValueOf<typeof newMessageItem>>(newMessageItem).forEach(([key, value]) => {
      if (Object.prototype.hasOwnProperty.call(currentMessageItemInfo, key)) {
        ;(currentMessageItemInfo as any)[key as keyof MessageItemInterface] = value
      }
    })
  }
}

function onDeleteMessageItem(messageId: string) {
  messageList.value.delete(messageId)
}

function onHistoryRecordListUpdate() {
  if (historyMenuSidebarRef.value) {
    historyMenuSidebarRef.value.historyRecordListUpdate()
  }
}

function onGetMessageRecordList(recordId: string) {
  currentSessionId.value = recordId

  const loadingCtl = window.$message.loading(`${t('home_module.switching_over')}...`)

  fetchMessageRecordList<
    {
      role: 'user' | 'assistant'
      agentId: string
      agentAvatar: string
      agentTitle: string
      content: string
      timestamp: number
      imageUrl: string
      reasoningContent: string
    }[]
  >(recordId)
    .then((res) => {
      if (res.data && Array.isArray(res.data)) {
        const messageListDraft: (string | MessageItemInterface)[][] = res.data.map((recordItem) => {
          return [
            nanoid(),
            {
              role: recordItem.role,
              agentId: recordItem.agentId,
              content: recordItem.content,
              isAnswerLoading: false,
              name: recordItem.agentTitle,
              avatar: recordItem.agentAvatar,
              timestamp: recordItem.timestamp,
              imageUrl: recordItem?.imageUrl || '',
              reasoningContent: recordItem.reasoningContent || '',
            },
          ]
        })

        messageList.value = new Map(messageListDraft as any)
      }
    })
    .catch(() => {
      window.$message.error(t('home_module.history_application_failed_please_try_again'))
    })
    .finally(() => {
      loadingCtl.destroy()
    })
}

function onClearSessionReferenceFile() {
  footerOperationRef.value && footerOperationRef.value.clearSessionReferenceFile()
}

function onSmartFormsStatusFreezeCheck(messageItem: MessageItemInterface) {
  /* 重置智能表单项目 */
  if (messageItem.smartFormInfo && messageItem.smartFormInfo.type) {
    messageList.value.forEach((item) => {
      if (item.smartFormInfo && item.smartFormInfo.type === messageItem.smartFormInfo?.type) {
        item.smartFormInfo.isDisabled = true
      }
    })
  }
}
</script>

<template>
  <div ref="homeContainerRef" class="relative h-full min-h-[650px] w-full overflow-hidden">
    <div
      class="bg-px-home-home_bg-png relative h-full w-full bg-contain bg-center bg-no-repeat pr-0 transition-[padding] duration-300 ease-in-out"
      :class="{ '!pr-[293px]': isShowHistoryMenu }"
    >
      <div class="flex h-full flex-col px-[5px] pb-[14px]">
        <AgentAbout
          v-model:question-content="questionContent"
          :message-list-length="messageList.size"
          :current-agent-application="currentAgentApplication"
        />

        <MessageList
          v-show="isShowMessageList"
          ref="messageListRef"
          v-model:editor-drawer-config="editorDrawerConfig"
          :message-list="messageList"
          @update-specify-message-item="onUpdateSpecifyMessageItem"
        />

        <FooterOperation
          ref="footerOperationRef"
          v-model:current-agent-application="currentAgentApplication"
          v-model:is-agent-responding="isAgentResponding"
          v-model:question-content="questionContent"
          v-model:current-fetch-event-source-controller="currentFetchEventSourceController"
          v-model:editor-drawer-config="editorDrawerConfig"
          :current-session-id="currentSessionId"
          :message-list-length="messageList.size"
          :is-not-show-back-bottom-btn="messageListRef?.isNotShowBackBottomBtn"
          @message-list-scroll-to-bottom="messageListScrollToBottom"
          @add-message-item="onAddMessageItem"
          @update-specify-message-item="onUpdateSpecifyMessageItem"
          @delete-message-item="onDeleteMessageItem"
          @create-new-session="onCreateNewSession"
          @history-record-list-update="onHistoryRecordListUpdate"
          @smart-forms-status-freeze-check="onSmartFormsStatusFreezeCheck"
        />
      </div>

      <HistoryMenuSidebar
        ref="historyMenuSidebarRef"
        v-model="isShowHistoryMenu"
        v-model:is-agent-responding="isAgentResponding"
        :current-fetch-event-source-controller="currentFetchEventSourceController"
        :current-session-id="currentSessionId"
        @get-message-record-list="onGetMessageRecordList"
        @create-new-session="onCreateNewSession"
        @history-record-list-update="onHistoryRecordListUpdate"
        @clear-session-reference-file="onClearSessionReferenceFile"
      />
    </div>

    <Transition name="mask" mode="out-in">
      <div
        v-show="isAgentInitLoading"
        class="z-100 absolute inset-0 flex flex-col items-center justify-center bg-[rgba(0,0,0,0.4)]"
      >
        <n-spin :size="38" />

        <div class="text-theme-color mt-[30px] text-[14px]">{{ t('common_module.loading') }}...</div>
      </div>
    </Transition>
  </div>
</template>

<style lang="scss" scoped>
.mask-enter-active,
.mask-leave-active {
  transition-timing-function: ease-in-out;
  transition-duration: 0.2s;
  transition-property: opacity;
}

.mask-enter-from,
.mask-leave-to {
  opacity: 0;
}
</style>
