<template>
  <div class="bm-main-box">
    <div class="bm-main-box-title">
      召回测试
      <span>根据给定的查询文本测试知识的召回效果</span>
    </div>
    <div class="mt-[var(--czr-gap)] flex flex-1 overflow-hidden">
      <div class="card rounded-bl-2 flex flex-1 flex-col gap-4">
        <div class="text-main" v-loading="state.loading">
          <div class="text-head">
            源文本
            <div class="__hover" @click="onModelConfig">
              {{ SearchMethodTypeMap.get(state.modelConfig.indexConfig?.type) }}
            </div>
          </div>
          <div class="text-content">
            <CzrFormColumn
              label-width="0px"
              width="100%"
              v-model:param="state.text"
              type="textarea"
              :transparent="true"
              :clearable="false"
            />
            <CzrButton
              class="test"
              type="primary"
              title="测试"
              @click="onTest"
            />
          </div>
        </div>
        <div class="flex flex-1 flex-col">
          <div class="__czr-title_1">记录</div>
          <div class="flex-1">
            <CzrTable
              v-loading="state.query.loading"
              :data="state.query.result.data"
              :head="state.query.head"
              :total="state.query.result.total"
              :page="state.query.page.pageNum"
              :pageSize="state.query.page.pageSize"
              @handlePage="onPage"
              @row-click="(row) => (state.text = row.content)"
            >
            </CzrTable>
          </div>
        </div>
      </div>
      <div
        class="card rounded-br-2 flex w-[26.25rem] flex-col space-y-4"
        v-loading="state.loading"
      >
        <div class="__czr-title_1">{{ state.backList.length }} 个召回段落</div>
        <div class="flex flex-1 flex-col gap-4 overflow-y-auto">
          <template v-for="(item, index) in state.backList">
            <div
              class="back-item"
              :style="{
                backgroundColor: `rgba(${colors[index % colors.length]}, 0.05)`,
              }"
            >
              <div class="back-item-head">
                <div
                  :style="{
                    backgroundColor: `rgba(${colors[index % colors.length]}, 1)`,
                  }"
                >
                  <SvgIcon name="box" color="#ffffff" size="15" />
                </div>
                Chunk-{{ index + 1 }}·{{ item.wordCount }} 字符
              </div>
              <div class="mt-2 text-[1.25rem] font-bold text-[#21262D]">
                {{ item.text }}
              </div>
              <div
                class="mt-[var(--czr-gap)] flex flex-wrap gap-2 text-sm text-[#576275]"
              >
                <template v-for="s in item.keywords?.split(',') || []">
                  <span>#{{ s }}</span>
                </template>
              </div>
              <div
                class="mt-4 h-[1px] w-full"
                :style="{
                  backgroundColor: `rgba(${colors[index % colors.length]}, 0.2)`,
                }"
              />
              <div
                class="mt-4 flex items-center gap-2 text-[0.75rem] text-[#576275]"
              >
                <img
                  :src="DictionaryStore.getFileIcon(item.name)"
                  class="h-4"
                />
                {{ item.name }}
              </div>
            </div>
          </template>
        </div>
      </div>
    </div>
  </div>
  <CzrDialog
    :show="state.modelConfig.show"
    title="检索方式"
    @onClose="state.modelConfig.show = false"
    @onSubmit="onSubmitModelConfig"
    width="62.5rem"
    height="auto"
    max-height="90%"
  >
    <CzrForm ref="ref_form" label-width="6.1rem">
      <modelConfig
        :index-method="false"
        :embedding="false"
        ref="ref_modelConfig"
      />
    </CzrForm>
  </CzrDialog>
</template>

<script setup lang="ts">
import { getCurrentInstance, nextTick, onMounted, reactive, ref } from 'vue'
import { v4 } from 'uuid'
import modelConfig from '@/views/manage/knowledge/model-config.vue'
import { SearchMethodTypeMap } from '@/types/knowledge'
import { datasetsCallback, queriesAnswer } from '@/api/modules/knowledge/test'
import { ElMessage } from 'element-plus'
import { useDictionaryStore } from '@/stores'

const DictionaryStore = useDictionaryStore()
const emit = defineEmits(['refresh'])
const props = defineProps({
  knowledge: <any>{},
})
const { proxy }: any = getCurrentInstance()
const colors = ['46, 155, 62', '0, 159, 188', '119, 69, 222', '255, 162, 84']
const state: any = reactive({
  loading: false,
  text: '',
  backList: [],
  query: {
    loading: false,
    head: [
      { value: 'source', label: '数据源', show: true },
      { value: 'content', label: '文本', show: true },
      {
        value: 'createTime',
        label: '时间',
        show: true,
        datetime: true,
        width: 180,
      },
    ],
    page: {
      pageNum: 1,
      pageSize: 20,
    },
    result: {
      total: 0,
      data: [],
    },
  },
  modelConfig: {
    show: false,
    indexConfig: null,
  },
})
const ref_modelConfig = ref()
const ref_form = ref()
const onPage = (pageNum, pageSize) => {
  state.query.page = {
    pageNum: pageNum,
    pageSize: pageSize,
  }
  const params = {
    datesetId: props.knowledge.id,
    page: state.query.page.pageNum,
    size: state.query.page.pageSize,
  }
  state.query.loading = true
  queriesAnswer(params)
    .then(({ data }: any) => {
      state.query.result.total = data.totalElements
      state.query.result.data = data.content
    })
    .catch(() => {})
    .finally(() => {
      state.query.loading = false
    })
}
const onModelConfig = () => {
  state.modelConfig.show = true
  nextTick(() => {
    ref_modelConfig.value.init({ indexConfig: state.modelConfig.indexConfig })
  })
}
const onSubmitModelConfig = () => {
  ref_form.value.submit().then(() => {
    state.modelConfig.indexConfig = ref_modelConfig.value.getData().indexConfig
    state.modelConfig.show = false
  })
}
const onTest = () => {
  if (!state.text.trim()) {
    ElMessage.warning('请输入源文本')
    return
  }
  state.loading = true
  datasetsCallback({
    datasetId: props.knowledge.id,
    indexConfig: JSON.stringify(state.modelConfig.indexConfig),
    context: state.text,
  })
    .then(({ data }: any) => {
      state.backList = data
    })
    .catch(() => {})
    .finally(() => {
      state.loading = false
    })
}
onMounted(() => {
  onPage(1, 10)
  state.modelConfig.indexConfig = JSON.parse(
    JSON.stringify(props.knowledge.indexConfig),
  )
})
</script>

<style lang="scss" scoped>
.bm-main-box {
  padding-left: 0;
  padding-right: 0;
  padding-bottom: 0;
}
.card {
  background-color: #ffffff;
  box-shadow: 0rem 0.06rem 0.25rem 0rem rgba(38, 110, 255, 0.2);
  border: 0.06rem solid #e6e8ea;
  padding: 1rem;
}
.text-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  border-radius: 0.25rem;
  .text-head {
    display: flex;
    align-items: center;
    padding: 0 1.5rem;
    background-image: url('@/assets/images/knowledge/knowledge-back-test.png');
    background-repeat: no-repeat;
    background-size: 100% 100%;
    height: 3.75rem;
    border-radius: 0.25rem 0.25rem 0 0;
    border: var(--czr-border);
    font-weight: bold;
    font-size: 1.25rem;
    color: #303133;
    > div {
      margin-left: auto;
      width: 5.63rem;
      height: 1.75rem;
      background: #ebf2ff;
      border-radius: 0.25rem;
      border: 1px solid rgba(var(--czr-main-color-rgb), 0.3);
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 0.75rem;
      color: var(--czr-main-color);
    }
  }
  .text-content {
    flex: 1;
    position: relative;
    :deep(.czr-form-column) {
      width: 100%;
      height: 100%;
      .el-form-item {
        width: 100%;
        height: 100%;
        .el-textarea__inner {
          width: 100%;
          height: 100%;
          padding: 0.75rem;
          resize: none;
          border-top-left-radius: 0;
          border-top-right-radius: 0;
        }
      }
    }
    .test {
      position: absolute;
      right: 1.5rem;
      bottom: 0.75rem;
    }
  }
}

.back-item {
  border-radius: 0.5rem;
  width: 100%;
  padding: 2rem 1rem 1rem;
  position: relative;
  .back-item-head {
    position: absolute;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    font-size: 0.75rem;
    color: #576275;
    gap: 0.5rem;
    > div:first-child {
      width: 2.5rem;
      height: 1.63rem;
      box-shadow: 0 0.13rem 0.13rem 0 rgba(0, 0, 0, 0.25);
      border-radius: 0.25rem 0 0.25rem 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
}
</style>
