<template>
  <el-row class="upload-doc-page">
    <el-col :lg="14" :md="18" :sm="24" :xl="14" :xs="24">
      <div class="upload-doc-page-back pointer" @click="router.go(-1)">
        <el-icon>
          <ArrowLeftBold />
        </el-icon>
        上传文档
      </div>
      <el-space>
        <span class="category-title">导入类目:</span>
        <span class="category-title">{{ query?.categoryName }}</span>
      </el-space>
      <div class="form-title">上传文档</div>
      <el-upload
        v-model:file-list="fileList"
        :auto-upload="false"
        :before-upload="beforeUpload"
        :limit="50"
        :on-change="startUpload"
        :on-exceed="handleExceed"
        :show-file-list="false"
        accept=".docx,.pdf,.txt,.md,.ppt,.pptx"
        action="#"
        class="upload-demo"
        drag
        multiple
        :loading="uploading"
      >
        <img alt="" src="@/assets/agent/chat/uploadFile.svg" />
        <div class="el-upload__text">
          点击或将文档拖拽到这里上传
          <p
            style="font-weight: 400; font-size: 12px; color: rgba(0, 0, 0, 0.4); line-height: 18px"
          >
            支持.pdf、.docx、.txt、.md、.pptx、.ppt等格式<br />
            单文件最大限制10MB，最多支持（{{ fileList.length }}/50）个
          </p>
        </div>
        <template #tip>
          <div
            class="el-upload__tip"
            style="display: flex; align-items: center; justify-content: space-between"
          >
            <span>
              共包含{{ fileList.length }}篇文档
              <span v-if="isSuccess !== 0">，{{ isSuccess }}篇文档上传完成</span>
              <span v-if="isLoading !== 0">，{{ isLoading }}篇正在上传中</span>
              <span v-if="isFail !== 0">，{{ isFail }}篇上传失败</span>
            </span>
            <span class="primary-text pointer" @click="handleViewAll">查看全部</span>
          </div>
        </template>
      </el-upload>
      <div class="form-title">
        文档打标
        <el-tooltip content="选择维度后，文档上传后根据文档内容从所选维度下自动挑选标签进行打标">
          <el-icon>
            <Warning />
          </el-icon>
        </el-tooltip>
      </div>
      <el-select
        class="tag-select"
        v-model="formData.labelIds"
        :loading="queryTagLoading"
        :remote-method="getTagData"
        filterable
        multiple
        placeholder="请输入搜索关键词"
        remote
        reserve-keyword
        style="width: 100%"
      >
        <el-option
          v-for="item in tagData"
          :key="item.id"
          :label="item.name"
          :value="item.id"
        />
      </el-select>
      <div class="form-title">解析方式</div>
      <el-radio-group class="card__radio" v-model="formData.parasType">
        <el-row :gutter="16">
          <el-col :span="12">
            <el-card :class="{'active': formData.parasType === 'NORMAL'}" shadow="never" @click.stop="formData.parasType = 'NORMAL'">
              <el-row :gutter="10" justify="space-between" style="height: 60px">
                <el-col :span="22">
                  <div style="font-size: 14px; color: #191919">普通解析</div>
                  <div style="font-weight: 400; font-size: 12px; color: #8c8c8c; line-height: 20px">
                    使用普通服务据解析文档，抽取文档内容、层级结构等信息
                  </div>
                </el-col>
                <el-col :span="2">
                  <el-radio size="large" value="NORMAL" />
                </el-col>
              </el-row>
            </el-card>
          </el-col>
          <el-col :span="12">
            <el-card :class="{'active': formData.parasType === 'HIGH'}" shadow="never" @click.stop="formData.parasType = 'HIGH'">
              <el-row :gutter="10" justify="space-between" style="height: 60px">
                <el-col :span="22">
                  <div style="font-size: 14px; color: #191919">高精度解析</div>
                  <div style="font-weight: 400; font-size: 12px; color: #8c8c8c; line-height: 20px">
                    使用大模型进行高精度图文混排、表格、公式解析
                  </div>
                </el-col>
                <el-col :span="2">
                  <el-radio size="large" value="HIGH" />
                </el-col>
              </el-row>
            </el-card>
          </el-col>
        </el-row>
      </el-radio-group>
<!--      <div class="form-title">文档预处理</div>
      <el-checkbox v-model="formData.informationDesensitization">信息脱敏</el-checkbox>
      <el-checkbox v-model="formData.outlierHandling">异常值处理</el-checkbox>
      <el-checkbox v-model="formData.dataStandardization">数据标准化</el-checkbox>
      <el-checkbox v-model="formData.dataDeduplication">数据去重</el-checkbox>-->
      <div style="width: 100%; text-align: right">
        <el-button :disabled="buttonDisabled" style="margin-top: 30px" type="primary" :loading="submitLoading" @click="handleImportDocument">导入文档库</el-button>
      </div>
    </el-col>
  </el-row>
  <ViewAllDoc
    ref="viewAllDocRef"
    :all-doc-number="fileList.length"
    :document-data="fileList"
    :is-fail-number="isFail"
    :is-loading-number="isLoading"
    :is-success-number="isSuccess"
    @onReUpload="retryUpload"
    @on-delete="handleDeleteDoc"
  />
</template>
<script lang="ts" setup>
import { ElMessage } from 'element-plus'
import { debounce, isEmpty, last, remove } from 'lodash-es'
import { computed, ref } from 'vue'
import router from '@/router'
import ViewAllDoc from './components/ViewAllDoc.vue'
import baseApi from '@/servers/base/api/index'
import api from '@/servers/finyx/api/index'
import { useRoute } from 'vue-router'
import { upload } from '@/api/dada'

const { query } = useRoute()


const formData = ref<any>({
  categoryId: query?.category,
  labelIds: [],
  parasType: 'NORMAL',
  informationDesensitization: false,
  outlierHandling: false,
  dataStandardization: false,
  dataDeduplication: false,
})

const fileList = ref<any>([])
const processingQueue = ref<any>([])
const maxConcurrent = 5 // 最大并发数
const maxFiles = 50 // 最大上传文件数
const uploading = ref(false)
const uploadedFiles = ref(0)
const totalFiles = ref(0)

const buttonDisabled = computed(() => fileList.value.length === 0 || isLoading.value !== 0)


const isSuccess = computed(() => fileList.value.filter((v: any) => v.msg === '上传成功')?.length)
const isLoading = computed(
  () => fileList.value.filter((v: any) => ['等待上传', '上传中...'].includes(v.msg))?.length
)
const isFail = computed(() => fileList.value.filter((v: any) => !['上传成功', '等待上传', '上传中...'].includes(v.msg))?.length)

// 允许的文件类型
const allowedFileTypes = ['.pdf','.docx', '.txt', '.md', '.pptx', '.ppt'] // 上传前钩子
const beforeUpload = (file) => {
  // 检查文件类型
  const fileName = file.name.toLowerCase()
  const fileExtension = fileName.substring(fileName.lastIndexOf('.'))
  const isAllowedType = allowedFileTypes.includes(fileExtension)

  // 检查文件大小 (10MB)
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isAllowedType) {
    ElMessage.error(`不支持的文件类型，仅支持: ${allowedFileTypes.join(', ')}`)
  }
  if (!isLt10M) {
    ElMessage.error('上传文件大小不能超过 10MB!')
  }

  // 初始化文件状态
  file.msg = '等待上传'

  return isAllowedType && isLt10M
}
// 文件超出限制处理
const handleExceed = (files, fileList) => {
  ElMessage.warning(`最多只能上传 ${maxFiles} 个文件`)
}

// 开始上传
const startUpload = debounce(
  () => {
    if (uploading.value) return
    if (fileList.value.length === 0) {
      ElMessage.warning('请选择要上传的文件')
      return
    }
    // 重置所有文件状态
    fileList.value.forEach((file) => {
      file.msg = '等待上传'
    })

    uploading.value = true
    uploadedFiles.value = 0
    totalFiles.value = fileList.value.length

    // 初始化处理队列
    processingQueue.value = [...fileList.value.slice(0, maxConcurrent)]

    // 开始处理队列
    processingQueue.value.forEach((file) => {
      uploadFile(file)
    })
  },
  300,
  { leading: false, trailing: true }
)

// 上传单个文件
const uploadFile = (file) => {
  // 更新文件状态
  updateFileStatus(file, '上传中...')
  const formData = new FormData()
  formData.append('file', file.raw)
  formData.append('bizType', 'AIAPPLICATION_AVATAR')

  // 模拟上传请求，实际使用时替换为真实的axios请求
  simulateUpload(formData, file)
    .then((res) => {
      file.path = res.path
      // file.format = res.fileType
      file.format = last(file.name.split('.')).toUpperCase()
      updateFileStatus(file, '上传成功')
      uploadedFiles.value++
      removeFromQueue(file)
      enqueueNextFile()
    })
    .catch((error) => {
      updateFileStatus(file, error?.msg || '上传失败')
      uploadedFiles.value++
      removeFromQueue(file)
      enqueueNextFile()
    })
}
// 更新文件状态消息
const updateFileStatus = (file, msg) => {
  const fileIndex = fileList.value.findIndex((item) => item.uid === file.uid)
  if (fileIndex !== -1) {
    fileList.value[fileIndex].msg = msg
  }
}

// 从队列中移除文件
const removeFromQueue = (file) => {
  const index = processingQueue.value.findIndex((item) => item.uid === file.uid)
  if (index !== -1) {
    processingQueue.value.splice(index, 1)
  }
}

const allSameValue = (arr, value) =>
  arr.every(item => item.msg === value);

// 加入下一个文件到队列
const enqueueNextFile = () => {
  if (uploadedFiles.value + processingQueue.value.length >= totalFiles.value) {
    // 所有文件都已处理完毕
    if (processingQueue.value.length === 0) {
      uploading.value = false
      if (fileList.value.length > 0) {
        if (allSameValue(fileList.value, '上传成功')) {
          ElMessage.success('全部上传完成')
        } else if (fileList.value.some((v: any) => v.msg === '上传失败')) {
          ElMessage.warning('全部处理完成')
        } else if (allSameValue(fileList.value, '上传失败')) {
          ElMessage.error('上传失败，请重新上传')
        }
      }
    }
    return
  }

  // 从fileList中取出下一个未处理的文件
  const nextFileIndex = uploadedFiles.value + processingQueue.value.length

  if (nextFileIndex < fileList.value.length) {
    const nextFile = fileList.value[nextFileIndex]
    // 检查文件状态，避免重复处理
    if (!['上传成功', '上传失败'].includes(nextFile.msg)) {
      processingQueue.value.push(nextFile)
      uploadFile(nextFile)
    } else {
      console.log('跳过已处理文件:', nextFile.name)
      enqueueNextFile() // 继续检查下一个文件
    }
  }
}
// 重试上传失败的文件
const retryUpload = (file) => {
  // 重置文件状态
  updateFileStatus(file, '等待上传')
  if (processingQueue.value.length < maxConcurrent) {
    processingQueue.value.push(file)
    uploadFile(file)
  }
}
// 删除文件
const handleDeleteDoc = (file) => {
  remove(fileList.value, (v: any) => v.name === file.name)
}

// 请求上传文件
const simulateUpload = async (formData, file) => {
  return new Promise(async (resolve, reject) => {
    try {
      await api.wendang.checkName1({ name: file.name })
      const data = await upload(formData)
      resolve(data)
    } catch (e) {
      if (e?.response?.data.errorMsg) {
        return reject({ msg: e?.response?.data.errorMsg })
      }
      reject({ msg: '上传失败' })
    }
  })
}

// 查看全部上传文档弹窗 ref
const viewAllDocRef = ref<any>(null)

const handleViewAll = () => {
  if (fileList.value.length <= 0) {
    return ElMessage.warning('请先上传文件后再查看全部！')
  }
  viewAllDocRef.value.open(fileList)
}

// 获取维度数据选择
const tagData = ref<any>([])
const queryTagLoading = ref<boolean>(false)
const getTagData = async (name: string) => {
  try {
    queryTagLoading.value = true
    tagData.value = await api.weidu.query10({ name })
  } catch (e) {
    ElMessage.error('获取维度失败！')
  } finally {
    queryTagLoading.value = false
  }
}


const submitLoading = ref<boolean>(false)

const handleImportDocument = debounce(async () => {
  if (isEmpty(fileList.value)) {
    return ElMessage.warning('请先上传文件后再提交！')
  }
  try {
    submitLoading.value = true
    const model = {
      ...formData.value,
      fdocumentSaveVOList: fileList.value.filter((v: any) => v.msg === '上传成功')
    }
    await api.wendang.batchInsert(model);
    ElMessage.success('文档导入成功！')
    router.go(-1)
  } catch (e) {
    ElMessage.error('文档导入失败！')
  } finally {
    submitLoading.value = false
  }
}, 1000)


</script>
<style lang="scss" scoped>
.upload-doc-page {
  &-back {
    display: flex;
    align-items: center;

    .el-icon {
      margin-right: 6px;
    }
  }
  .tag-select {
    &:deep(.el-tag) {
      background: rgba(48,103,239,0.06);
      border-radius: 4px 4px 4px 4px;
      border: 1px solid rgba(48,103,239,0.5);
    }
    &:deep(.el-select__tags-text), &:deep(.el-tag__close) {
      color: #3067EF;
    }
    &:deep(.el-tag .el-tag__close:hover) {
      background: #3067EF;
      color: #fff;
    }
  }

  .category-title {
    margin-top: 30px;
    margin-bottom: 20px;
    font-weight: 500;
    font-size: 16px;
    color: #191919;
  }

  .form-title {
    font-weight: 400;
    font-size: 14px;
    color: #191919;
    margin-top: 30px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;

    .el-icon {
      margin-left: 5px;
    }
  }

  .radio-card {
    line-height: 22px;

    &.active {
      border-color: var(--el-color-primary);
      color: var(--el-color-primary);
    }
  }
}
</style>
