<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { onBeforeRouteLeave } from 'vue-router'
import { PAGINATION_PAGE_SIZES } from '@/const/index'
import { Icon } from '@iconify/vue';
import { objectClean } from '@/utils';
import {
  fetchQueryDocList,
  fetchAddSetDoc,
  fetchUpdateSetDoc,
  fetchDeleteSetDoc,
  fetchBackOffSetDoc,
  fetchAnalysisSetDoc,
  fetchUploadImgFile,
  fetchGetDocSetList,
  fetchSubmitSetDoc,
  fetchAuditSetDoc
} from '@/service/api';

const docTypeCodeOptions = [
  { label: '渠道业务规则文档', value: '01' },
  { label: '产品相关监管规定文档', value: '02' },
  { label: '产品相关宣传素材文档', value: '03' },
  { label: '个养产品信息文档', value: '04' },
  { label: '商养产品信息文档', value: '05' },
]
const docStatusOptions = [
  { label: '草稿', value: '00' },
  { label: '待审核', value: '01' },
  { label: '审核通过', value: '02' },
  { label: '驳回', value: '03' },
]
const auditDocStatusOptions = [
  { label: '审核通过', value: '02' },
  { label: '驳回', value: '03' },
]
const analyzeStatusOptions = [
  { label: '待解析', value: '00' },
  { label: '解析中', value: '01' },
  { label: '解析完成', value: '02' },
  { label: '解析失败', value: '03' },
  { label: '撤回解析', value: '04' },
]

const pagination = ref({
  pageSize: 10,
  itemCount: 0,
  pageNum: 1
});
function handlePageUpdate(page: number) {
  pagination.value.pageNum = page;
  getListData();
}
function handlePageSizeUpdate(pageSize: number) {
  pagination.value.pageNum = 1;
  pagination.value.pageSize = pageSize;
  getListData();
}

function createQueryParams() {
  return {
    docName: '',
    docTypeCode: null,
    docStatus: null,
    analyzeStatus: null,
    createTime: null,
    createTimeStart: '',
    createTimeEnd: '',
    auditTime: null,
    auditTimeStart: '',
    auditTimeEnd: ''
  };
}
const loading = ref(false);
const listData = ref([]);
const queryParams = ref(createQueryParams());

/** 检索 */
function handleQuery() {
  pagination.value = {
    pageSize: 10,
    itemCount: 0,
    pageNum: 1
  }
  getListData();
}
/** 重置检索 */
function handleResetQuery() {
  queryParams.value = { ...createQueryParams() };
  pagination.value = {
    pageSize: 10,
    itemCount: 0,
    pageNum: 1
  }
  getListData();
}
const timer = ref<any>(null)
function startPolling() {
  clearTimeout(timer.value)
  timer.value = null
  timer.value = setTimeout(() => {
    getListData(false)
  }, 5000);
}

async function getListData(showLoading = true) {
  loading.value = showLoading;
  const { pageNum, pageSize } = pagination.value;
  const { docName, docTypeCode, docStatus, analyzeStatus, createTime, auditTime } = queryParams.value;
  const params = {
    docName,
    docTypeCode,
    docStatus,
    analyzeStatus,
    createTimeStart: createTime ? `${createTime[0]} 00:00:00` : '',
    createTimeEnd: createTime ? `${createTime[1]} 23:59:59` : '',
    auditTimeStart: auditTime ? `${auditTime[0]} 00:00:00` : '',
    auditTimeEnd: auditTime ? `${auditTime[1]} 23:59:59` : '',
    pageNum,
    pageSize
  };
  const { data } = await fetchQueryDocList(objectClean(params));
  if (data?.ok) {
    listData.value = data.data.records;
    pagination.value.itemCount = data.data.total;
    const hasParsingData = listData.value.some((item: any) => item.analyzeStatus === '01')
    if (hasParsingData) {
      startPolling()
    }
  }
  loading.value = false;
}

// 00-待解析 01-解析中 02-解析完成 03-解析失败 04-撤回解析
function filterAnalyzeStatus(status: string) {
  switch (status) {
    case '00':
      return '待解析'
      break;
    case '01':
      return '解析中'
      break;
    case '02':
      return '解析完成'
      break;
    case '03':
      return '解析失败'
      break;
    case '04':
      return '撤回解析'
      break;
    default:
      return '未知'
      break;
  }
}

// 00-草稿 01-待审核 02-审核通过 03-审核驳回
function filterDocStatus(status: string) {
  switch (status) {
    case '00':
      return '草稿 '
      break;
    case '01':
      return '待审核 '
      break;
    case '02':
      return '审核通过'
      break;
    case '03':
      return '审核驳回'
      break;
    default:
      return '未知'
      break;
  }
}


const isShowAddDocModal = ref(false)
const addDocForm = ref<any>({
  docTypeCode: null,
  docUrl: '',
  docName: '',
  docCode: ''
})
const addDocRules = ref({
  docTypeCode: {
    required: true,
    trigger: ['blur', 'change'],
    message: '请选择 文档类型'
  },
  docUrl: {
    required: true,
    trigger: ['blur', 'change'],
    message: '请选择 上传文件'
  },
  docStatus: {
    required: true,
    trigger: ['blur', 'change'],
    message: '请选择 审核结论'
  },
})
const addDocFormRef = ref()
function onCloseAddDocModal() {
  addDocForm.value = {
    docTypeCode: null,
    docUrl: '',
    docName: '',
    docCode: ''
  }
  isShowAddDocModal.value = false
}
const addDocLoading = ref(false)
function handleValidateAddDocForm() {
  addDocFormRef.value?.validate((errors: any) => {
    if (!errors) {
      submitAddProdcutDoc()
    }
    else {
      console.log(errors)
    }
  })
}

const defaultFileList = ref<any>([])

const operateType = ref('')
function onAddDoc() {
  operateType.value = 'add'
  defaultFileList.value = []
  addDocForm.value = {
    docTypeCode: null,
    docUrl: '',
    docName: '',
    docCode: ''
  }
  isShowAddDocModal.value = true
}

function onEditDoc(data: any) {
  operateType.value = 'edit'
  addDocForm.value = {
    ...data
  }
  defaultFileList.value = [
    {
      id: addDocForm.value.docCode,
      name: addDocForm.value.docName,
      status: 'finished'
    }
  ]
  isShowAddDocModal.value = true
}
function onPreDoc(data: any) {
  operateType.value = 'preview'
  addDocForm.value = {
    ...data
  }
  defaultFileList.value = [
    {
      id: addDocForm.value.docCode,
      name: addDocForm.value.docName,
      status: 'finished'
    }
  ]
  isShowAddDocModal.value = true
}
const ossConfig = ref(null)

async function handlePreview(file: any) {
  window.open(addDocForm.value.tempDocUrl)
}
async function submitAddProdcutDoc() {
  addDocLoading.value = true
  const params = {
    docTypeCode: addDocForm.value.docTypeCode,
    docUrl: addDocForm.value.docUrl,
    docName: addDocForm.value.docName,
    docCode: addDocForm.value.docCode,
    docStatus: addDocForm.value.docStatus,
    auditDesc: addDocForm.value.auditDesc
  }
  const apis = {
    add: fetchAddSetDoc,
    edit: fetchUpdateSetDoc,
    audit: fetchAuditSetDoc
  }
  const res = await apis[operateType.value](params)
  if (res.data) {
    getListData()
    onCloseAddDocModal()
    window.$message?.success('成功');
  }
  addDocLoading.value = false
}

async function customRequest({
  file,
  data,
  headers,
  withCredentials,
  action,
  onFinish,
  onError,
  onProgress
}: any) {
  const fm = new FormData()
  fm.append('file', file.file)
  fm.append('scene', 'product')
  const res = await fetchUploadImgFile(fm, {
    withCredentials
  })
  if (res.data) {
    addDocForm.value.docUrl = res.data.data.fullUrl
    addDocForm.value.docName = file.name
    onFinish()
  } else {
    onError()
  }
}

function onDeleteProductDoc(data: any) {
  window.$dialog?.info({
    title: '提示',
    content: '您确定要删除当前产品文档吗？',
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: async () => {
      const res = await fetchDeleteSetDoc({
        ...data,
      });
      if (res?.data?.ok) {
        window.$message?.success('操作成功');
        getListData()
      }
    }
  });
}

async function onSubmitProductDoc(data: any) {
  const res = await fetchSubmitSetDoc({
    ...data
  })
  if (res.data) {
    window.$message?.success('操作成功');
    getListData()
  }
}

async function onBackOffDoc(data: any) {
  const res = await fetchBackOffSetDoc({
    ...data
  })
  if (res.data) {
    window.$message?.success('操作成功');
    getListData()
  }
}
async function onAnalysisDoc(data: any) {
  const res = await fetchAnalysisSetDoc({
    ...data
  })
  if (res.data) {
    window.$message?.success('操作成功');
    getListData()
  }
}

function onAuditDoc(data: any) {
  operateType.value = 'audit'
  addDocForm.value = {
    ...data,
    docStatus: null,
    auditDesc: ''
  }
  defaultFileList.value = [
    {
      id: addDocForm.value.docCode,
      name: addDocForm.value.docName,
      status: 'finished'
    }
  ]
  isShowAddDocModal.value = true
}


onMounted(() => {
  getListData()
})

onBeforeRouteLeave((to, from, next) => {
  clearTimeout(timer.value)
  timer.value = null
  next()
})

</script>
<template>
  <div>
    <n-card class="h-full shadow-sm rounded-8px">
      <n-grid cols="1 s:2 m:3 l:4 xl:5 2xl:6" responsive="screen" x-gap="12" y-gap="12">
        <n-grid-item>
          <p class="mb-6px">文档名称：</p>
          <n-input clearable v-model:value="queryParams.docName" placeholder="文档名称"></n-input>
        </n-grid-item>
        <n-grid-item>
          <p class="mb-6px">文档类型：</p>
          <n-select v-model:value="queryParams.docTypeCode" clearable placeholder="文档类型"
            :options="docTypeCodeOptions" />
        </n-grid-item>
        <n-grid-item>
          <p class="mb-6px">文档状态：</p>
          <n-select v-model:value="queryParams.docStatus" clearable placeholder="文档状态" :options="docStatusOptions" />
        </n-grid-item>
        <n-grid-item>
          <p class="mb-6px">解析状态：</p>
          <n-select v-model:value="queryParams.analyzeStatus" clearable placeholder="解析状态"
            :options="analyzeStatusOptions" />
        </n-grid-item>
        <n-grid-item>
          <p class="mb-6px">创建时间：</p>
          <n-date-picker v-model:formatted-value="queryParams.createTime" :actions="[]" close-on-select
            value-format="yyyy-MM-dd" placeholder="创建时间" type="daterange" start-placeholder="开始" end-placeholder="结束"
            clearable />
        </n-grid-item>
        <n-grid-item>
          <p class="mb-6px">审核时间：</p>
          <n-date-picker v-model:formatted-value="queryParams.auditTime" :actions="[]" close-on-select
            value-format="yyyy-MM-dd" placeholder="审核时间" type="daterange" start-placeholder="开始" end-placeholder="结束"
            clearable />
        </n-grid-item>
        <n-grid-item class="flex items-end">
          <n-space>
            <n-button secondary strong type="primary" @click="handleQuery"> 查 询 </n-button>
            <n-button secondary strong @click="handleResetQuery">重 置</n-button>
          </n-space>
        </n-grid-item>
      </n-grid>
    </n-card>
    <n-card class="shadow-sm rounded-8px mt-12px">
      <n-space class="mb-12px">
        <n-button strong type="primary" @click="onAddDoc"> 新增文档 </n-button>
      </n-space>
      <n-spin :show="loading">
        <vxe-table :column-config="{ resizable: true }"
          :seq-config="{ startIndex: (pagination.pageNum - 1) * pagination.pageSize }" auto-resize
          :row-config="{ isHover: true }" stripe border :data="listData">
          <vxe-column type="seq" title="序号" width="60"></vxe-column>
          <vxe-column min-width="200" field="docName" title="文档名称"></vxe-column>
          <vxe-column min-width="200" field="docTypeName" title="文档类型"></vxe-column>
          <vxe-column min-width="120" field="docStatus" title="文档状态">
            <template #default="{ row }">
              <span>{{ filterDocStatus(row.docStatus) }}</span>
            </template>
          </vxe-column>
          <vxe-column min-width="120" field="analyzeStatus" title="解析状态">
            <template #default="{ row }">
              <span>{{ filterAnalyzeStatus(row.analyzeStatus) }}</span>
              <n-spin v-if="row.analyzeStatus === '01'" class="define-mini-size" :stroke-width="22" size="small" />
            </template>
          </vxe-column>
          <vxe-column min-width="200" field="createBy" title="创建人"></vxe-column>
          <vxe-column min-width="200" field="createTime" title="创建时间"></vxe-column>
          <vxe-column min-width="200" field="auditBy" title="审核人"></vxe-column>
          <vxe-column min-width="200" field="auditTime" title="审核时间"></vxe-column>
          <vxe-column field="title" title="操作" fixed="right" min-width="120">
            <template #default="{ row }">
              <n-space>
                <n-button @click="onEditDoc(row)" v-if="row.docStatus === '00' || row.docStatus === '03'" strong text
                  type="info">编辑</n-button>
                <n-button @click="onSubmitProductDoc(row)" v-if="row.docStatus === '00' || row.docStatus === '03'"
                  strong text type="info">提交</n-button>
                <n-button v-if="row.docStatus === '00' || row.docStatus === '03'" strong text type="info"
                  @click="onDeleteProductDoc(row)">删除</n-button>
                <n-button @click="onPreDoc(row)" v-if="row.docStatus !== '00' && row.docStatus !== '03'" strong text
                  type="info">详情</n-button>
                <n-button @click="onAuditDoc(row)" v-if="row.docStatus === '01'" strong text type="info">审核</n-button>
                <n-button @click="onBackOffDoc(row)" v-if="row.analyzeStatus && row.analyzeStatus === '02'" strong text
                  type="info">撤回解析</n-button>
                <n-button @click="onAnalysisDoc(row)"
                  v-if="row.analyzeStatus && row.analyzeStatus !== '00' && row.analyzeStatus !== '01'" strong text
                  type="info">重新解析</n-button>
              </n-space>
            </template>
          </vxe-column>
        </vxe-table>
      </n-spin>
      <div v-if="pagination.itemCount !== 0" class="w-full flex justify-end mt-4">
        <n-pagination v-model:page="pagination.pageNum" v-model:page-size="pagination.pageSize"
          :item-count="pagination.itemCount" :page-sizes="PAGINATION_PAGE_SIZES" :on-update:page="handlePageUpdate"
          :on-update:page-size="handlePageSizeUpdate" show-size-picker>
          <template #prefix="{ itemCount, startIndex }">
            <div class="text-[#333]">共 <span class="text-primary">{{ pagination.itemCount }}</span> 条</div>
          </template>
        </n-pagination>
      </div>
    </n-card>

    <n-modal v-model:show="isShowAddDocModal">
      <n-card style="max-width: 600px;" title="新增文档" :bordered="false" size="huge" role="dialog" aria-modal="true">
        <template #header-extra>
          <Icon icon="ic:sharp-close" class="text-size-22px cursor-pointer" @click="isShowAddDocModal = false" />
        </template>
        <n-form ref="addDocFormRef" :model="addDocForm" :rules="addDocRules" label-placement="left" label-width="auto"
          require-mark-placement="right-hanging" :style="{
            maxWidth: '640px',
          }">
          <n-form-item label="文档类型" path="docTypeCode">
            <n-select :disabled="operateType === 'preview'" v-model:value="addDocForm.docTypeCode" clearable
              placeholder="文档类型" :options="docTypeCodeOptions" />
          </n-form-item>
          <n-form-item label="上传文档" path="docTypeCode">
            <div>
              <n-alert type="info" :bordered="false">
                <div>支持上传单个.txt/.docx/pdf/.doc/.wps/.ett/.xls/.xlsx格式文件</div>
              </n-alert>
              <br />
              <n-upload :disabled="operateType === 'preview'" @preview="handlePreview"
                :default-file-list="defaultFileList" accept=".txt,.docx,.pdf,.doc,.wps,.ett,.xls,.xlsx" :max="1"
                action="https://naive-upload.free.beeceptor.com/" :headers="{
            'naive-info': 'hello!',
          }" :data="{
            'naive-data': 'cool! naive!',
          }" :custom-request="customRequest">
                <n-button>上传文件</n-button>
              </n-upload>
            </div>
          </n-form-item>
          <n-form-item
            v-if="operateType === 'audit' || operateType === 'preview' && (addDocForm.docStatus === '02' || addDocForm.docStatus === '03')"
            label="审核结论" path="docStatus">
            <n-select :disabled="operateType === 'preview'" v-model:value="addDocForm.docStatus" clearable
              placeholder="审核结论" :options="auditDocStatusOptions" />
          </n-form-item>
          <n-form-item
            v-if="operateType === 'audit' || operateType === 'preview' && (addDocForm.docStatus === '02' || addDocForm.docStatus === '03')"
            label="审核意见" path="auditDesc">
            <n-input maxlength="200" show-count :disabled="operateType === 'preview'" type="textarea"
              v-model:value="addDocForm.auditDesc" placeholder="审核意见" />
          </n-form-item>
        </n-form>
        <template #footer v-if="operateType !== 'preview'">
          <n-space justify="center">
            <n-button @click="onCloseAddDocModal">取消</n-button>
            <n-button :loading="addDocLoading" type="primary" @click="handleValidateAddDocForm">
              <span v-if="operateType === 'audit'">确定</span>
              <span v-else>保存</span>
            </n-button>
          </n-space>
        </template>
      </n-card>
    </n-modal>
  </div>
</template>

<style>
.define-mini-size .n-base-loading {
  font-size: 12px !important;
  margin-left: 4px;
}
</style>
