<!-- 参考文献抽屉组件 -->

<script setup lang="ts">
import { ref, reactive, type Ref } from "vue";
import ReferenceSearchBox from "./ReferenceSearchBox.vue";
import ReferenceSearchResultItem from "./ReferenceSearchResultItem.vue";
import type { ChapterSearchDocResponse, ChapterSearchRequest } from "@/types/search.types"
import * as chapterSearchService from "@/services/chapterSearch.service"
import * as paperSectionService from "@/services/paperSection.service"
import { CompLog } from "@/libs/log.lib";
import SpinComponent from "@/components/SpinComponent.vue";

const props = defineProps({
  reportName: {
    type: String,
    required: true,
  },
  reportKeywords: {
    type: String,
    required: true,
  },
  chapterKeywords: {
    type: Array<String>,
    required: true,
  }
});

const emits = defineEmits<{
  (e: "insert", text: string): void;
  (e: "close"): void;
  (e: "recordUse", sectionId: number): void;
}>();

// 组件可见状态
const visible = ref<boolean>(false);
// 章节搜索结果总数量
const total = ref(0)
// 章节搜索结果
const referenceSearchResult: Ref<ChapterSearchDocResponse[]> = ref([]);
// 文献章节段落内容是否使用ref
const paperSectionUsage = ref<Record<number, boolean>>({})
// 章节搜索状态
const loading = ref(false)
// 翻页
const pagination = reactive({
  page: 1,
  size: 10,
})
// 重新检索的查询词
const queryKeywords = ref<string[]>([])
// 在结果中检索的查询
const queryWithInKeywords = ref<string[]>([])

function getFrom(page?: number) {
  return (Math.max(1, page || 1) - 1) * pagination.size
}

function getDefaultKeywords(): string[] {
  return props.chapterKeywords as string[]
}

function getSearchRequest(): ChapterSearchRequest {
  const request: ChapterSearchRequest = {
    reportName: props.reportName || '',
    reportKeywords: props.reportKeywords || '',
    chapterKeywords: getDefaultKeywords(),
    queryKeywords: queryKeywords.value,
    queryWithInKeywords: queryWithInKeywords.value,
    from: getFrom(pagination.page)
  }
  return request
}

function querySectionUsage(sectionIds: number[]) {
  paperSectionService.query(sectionIds).then((usages) => {
    paperSectionUsage.value = usages
  })
}

function search(request: ChapterSearchRequest) {
  loading.value = true
  referenceSearchResult.value = []
  chapterSearchService.search(request).then((resp) => {
    loading.value = false
    total.value = resp.total
    referenceSearchResult.value = resp.items

    querySectionUsage(resp.items.map(item => item.id))
  }).catch((err) => {
    CompLog.logErr("ReferenceDraw")(err)
    loading.value = false
  })
}

function onPageChange(page: number) {
  pagination.page = page
  search(getSearchRequest())
}

function onReferenceSearchBoxSearch(queryKeywordsIn: string[]) {
  pagination.page = 1
  queryKeywords.value = queryKeywordsIn
  queryWithInKeywords.value = []
  search(getSearchRequest())
}

function onReferenceSearchWithInSearch(queryWithInKeywordsIn: string[]) {
  pagination.page = 1
  queryWithInKeywords.value = queryWithInKeywordsIn
  search(getSearchRequest())
}

function onSectionRecordUse(sectionId: number) {
  paperSectionService.record(sectionId).then(() => {
    paperSectionUsage.value[`${sectionId}`] = true
  })
}

function onSectionRecordCancel(sectionId: number) {
  paperSectionService.cancel(sectionId).then(() => {
    paperSectionUsage.value[`${sectionId}`] = false
  })
}

function serialNumber(index: number) {
  index += 1;
  return (pagination.page - 1) * pagination.size + index;
}

const onClose = () => {
  visible.value = false;
  emits("close")
};

const show = () => {
  visible.value = true;
  const keywords = props.chapterKeywords
  if (keywords && keywords.length > 0) {
    search(getSearchRequest())
  }
};

defineExpose({
  show
});
</script>

<template>
  <a-drawer
    :width="'60%'"
    title="检索参考文献"
    placement="right"
    :visible="visible"
    @close="onClose"
    class="reference-drawer"
  >
    <template #extra>
      <span>项目名称：{{ reportName }}</span>
      <a-divider type="vertical" />
      <span>关键词：{{ reportKeywords }}</span>
      <a-divider type="vertical" />
      <span>章节关键词：{{ chapterKeywords.join(", ") }}</span>
    </template>
    <ReferenceSearchBox @search="onReferenceSearchBoxSearch" @search-with-in="onReferenceSearchWithInSearch" />
    <a-divider orientation="left">
      <span class="total">章节数量：共 {{ total }} 条</span>
    </a-divider>
    <SpinComponent :spinning="loading">
      <div v-for="(item, index) in referenceSearchResult" :key="index">
        <ReferenceSearchResultItem
          :data="item"
          :used="paperSectionUsage[item.id] || false"
          :serialNumber="serialNumber(index)"
          @insert="emits('insert', $event)"
          @record-use="onSectionRecordUse"
          @record-cancel="onSectionRecordCancel"
        />
        <a-divider class="result-item-divider" v-if="index < referenceSearchResult.length - 1" />
      </div>
      <div class="pigination-wrap">
        <a-pagination
          :current="pagination.page"
          :pageSize="pagination.size"
          :total="total"
          :show-size-changer="false"
          size="small"
          @change="onPageChange"
        />
      </div>
    </SpinComponent>
  </a-drawer>
</template>

<style scoped lang="scss">
.result-item-divider {
  margin: 1.2em 0;
}

.total {
  font-size: 0.8em;
}

.pigination-wrap {
  text-align: right;
  margin-top: 1em;
}
</style>
