<!--
 * @Author: zhuMingXi
 * @Date: 2025/07/26 14:35:00
 * @LastEditors: zhuMingXi
 * @LastEditTime: 2025/07/26 14:35:00
 * @Description:  编辑检验方案弹窗
 * @FilePath:  D:\yiqun\yudao-admin\yudao-ui-admin-vue3\src\views\pressure\taskorder\components\AddInspectionplanDetail.vue
 -->
<template>
  <ContentWrap
    v-show="!showInlineEditRecord"
    title="检验方案"
    class="check-record-wrapper"
    v-loading="pdfLoading"
  >
    <div class="designer-inner" ref="wrapperContainerRef">
<!--      <SpreadViewer :initData="initData" ref="spreadRef" />-->
      <SpreadViewer :initData="editData" ref="editSpreadRecordRef" @saveSuccess="saveSuccessRecord"/>
    </div>
    <div class="operation-inner relative">
      <div class="btn-list">
        <template v-if="['add', 'edit'].includes(isEdit)">
          <el-button type="primary" @click="handleSubmitBefore">提交审核</el-button>
<!--          <el-button type="primary" plain @click="handleEditSpreadRecord">编辑封面</el-button>-->
        </template>
        <el-button type="default" plain @click="handleCloseModal">取 消</el-button>
      </div>
      <div class="operation-item" style="max-height: calc(100% / 2); overflow-y: auto">
        <div class="item-header"> 方案上传 </div>
        <div class="item-content">
          <el-upload
            ref="uploadRef"
            action="#"
            v-model:file-list="fileList"
            :http-request="handlePostFile"
            :auto-upload="false"
            :disabled="isEdit === 'view'"
            :limit="1"
            :on-change="handleChange"
            :on-error="handleUploadError"
            :on-exceed="handleExceed"
            :accept="accept"
            drag
          >
            <Icon icon="ep:upload" />
            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
            <template #tip>
              <div class="el-upload__tip text-center">
                <span>{{ `仅允许导入${accept} 格式文件。` }}</span>
              </div>
            </template>
          </el-upload>
        </div>
      </div>
      <div class="operation-item">
        <div class="item-header"> 退回原因 </div>
        <div class="item-content">
          <el-input
            v-model="returnReason"
            :autosize="{ minRows: 10, maxRows: 50 }"
            type="textarea"
            readonly
          />
        </div>
      </div>
    </div>
  </ContentWrap>

  <!-- 检验录入-模板 -->
  <CustomDialog v-model="showInlineEditRecord" title="检验录入" :show-footer="false" fullscreen>
<!--    <SpreadViewer :initData="editData" ref="editSpreadRecordRef" @saveSuccess="saveSuccessRecord"/>-->
  </CustomDialog>

  <CustomDialog
    ref="customUnitDialogRef"
    title="选择审核人"
    v-model="approvalUserVisible"
    width="650px"
    :dialogAttrs="{ zIndex: 10006 }"
  >
    <el-form ref="formRef" :model="formData" :rules="formRules" label-width="135px">
      <el-form-item label="检验方案审核人" prop="inspectionAuditId">
        <el-select v-model="formData.inspectionAuditId" clearable placeholder="请选择">
          <el-option
            v-for="item in optionList.schemeReviewerList"
            :key="item.id"
            :label="item.nickname"
            :value="item.id"
          />
        </el-select>
      </el-form-item>

<!--      <el-form-item label="检验方案批准人" prop="inspectionApproveId">-->
<!--        <el-select v-model="formData.inspectionApproveId" clearable placeholder="请选择">-->
<!--          <el-option-->
<!--            v-for="item in optionList.schemeApproveList"-->
<!--            :key="item.id"-->
<!--            :label="item.nickname"-->
<!--            :value="item.id"-->
<!--          />-->
<!--        </el-select>-->
<!--      </el-form-item>-->
    </el-form>
    <template #footer>
      <el-button @click="approvalUserVisible = false">取消</el-button>
      <el-button type="primary" @click="handleSubmitUser">确定</el-button>
    </template>
  </CustomDialog>
</template>
<script lang="tsx" setup>
import { BoilerTaskOrderApi } from '@/api/pressure2/boilertaskorder'
import {defineModel, PropType, ref} from 'vue'
import VuePdfEmbed from 'vue-pdf-embed'
import EditInspectionplanReport from './EditInspectionplanReport.vue'
import { getPressureReportTemplatePDF } from '@/api/pressure/reportTemplate'
import { ElForm, UploadFile, UploadProps, UploadRequestOptions } from 'element-plus'
import { uploadFile } from '@/api/common'
import VueOfficeDocx from '@vue-office/docx/lib/v3/vue-office-docx.mjs'
import '@vue-office/docx/lib/v3/index.css'
import * as UserGroupApi from '@/api/bpm/userGroup'
import * as UserApi from '@/api/system/user'
import { debounce } from 'lodash-es'
import { PressureReportType } from '@/utils/constants'
import SpreadDesigner from "@/components/SpreadDesigner/index.vue";
import {DynamicTbValApi} from "@/api/pressure2/dynamictbval";
import * as GC from "@grapecity-software/spread-sheets";
import {getPDF, getStandardTemplateInfo} from "@/api/laboratory/standard/template";
import {buildFileUrl} from "@/utils";
import axios from "axios";
import {editReport} from "@/utils/reportUtil";
import {DynamicTbColApi} from "@/api/pressure2/dynamictbcol";
import {SpreadViewer} from "@/components/DynamicReport";
import {InitParams} from "@/components/DynamicReport/SpreadInterface";

const props = defineProps({
  taskOrderDetail: {
    type: Object,
    default: () => ({})
  },
  inspectionplanDetail: {
    type: Object,
    default: () => ({})
  },
  isEdit: {
    type: String as PropType<'add' | 'edit' | 'view'>,
    required: true
  },
  editInspectionplanParams: {
    type: Object,
    default: () => ({})
  }
})

const emits = defineEmits(['success', 'refresh'])
const visible = defineModel('visible', { type: Boolean, default: false })
const returnReason = ref(props.inspectionplanDetail?.returnReason)

// 选择审核人
const formRef = ref<InstanceType<typeof ElForm>>()
const formData = ref<Recordable>({})
const formRules = reactive({
  inspectionAuditId: [{ required: true, message: '请选择审核人', trigger: 'change' }],
  inspectionApproveId: [{ required: true, message: '请选择批准人', trigger: 'change' }]
})

const optionList = reactive<{
  schemeReviewerList: Recordable[]
  schemeApproveList: Recordable[]
}>({
  schemeReviewerList: [],
  schemeApproveList: []
})
const approvalUserVisible = ref(false)
// 获取审核人信息
const getSchemeReviewerList = async () => {
  try {
    const { inspectionAuditId, inspectionApproveId } = await UserApi.getApprovalDetail({})
    formData.value = {
      inspectionAuditId,
      inspectionApproveId
    }
    optionList.schemeReviewerList = await UserGroupApi.getUserGroupUserList({
      category: 600,
      status: 0
    })
    optionList.schemeApproveList = await UserGroupApi.getUserGroupUserList({
      category: 700,
      status: 0
    })
    approvalUserVisible.value = true
  } catch (error) {}
}
const handleSubmitUser = () => {
  formRef.value?.validate(async (valid) => {
    if (valid) {
      handleSubmitConfirm()
    }
  })
}

// PDF相关状态
const pdfLoading = ref(false)

const showInlineEditRecord = ref(false)
const handleEditSpreadRecord = () => {
  editPreview()
  showInlineEditRecord.value = true
}
const handleSuccess = (info) => {
  // 更新相关的信息，reportId prepareJson 等
  console.log('handleSuccess-info:', info )
  emits('success', info)
  initPreview()
}

const uploadRef = ref()
const fileList = ref<UploadFile[]>([]) // 文件列表
const accept = '.docx,.pdf'
const fileLoading = ref(false) // 表单的加载中

// 获取文件类型
const getFileExtension = (fileName: string) => {
  return fileName.split('.').pop()?.toLowerCase()
}
const previewUrl = ref()
const getPreviewFileUrl = (file: File) => {
  let fileReader = new FileReader()
  fileReader.onload = () => {
    previewUrl.value = fileReader.result
  }
  if (getFileExtension(file.name) === 'docx') fileReader.readAsArrayBuffer(file)
  else {
    const pdfBlob = new Blob([file], { type: 'application/pdf' })
    previewUrl.value = URL.createObjectURL(pdfBlob)
  }
}

// 文件类型校验
const handleChange: UploadProps['onChange'] = (file, uploadFiles) => {
  console.log(file, uploadFiles)
  const allowedExtensions = accept.toLowerCase().split(',')
  const fileExt = '.' + (getFileExtension(file.name) || '')
  if (!allowedExtensions.includes(fileExt)) {
    ElMessage.error(`不支持的文件类型，仅允许上传: ${allowedExtensions.join(',')}类型文件`)
    uploadFiles.splice(uploadFiles.indexOf(file), 1)
    return false // 阻止上传
  }
  previewUrl.value = null
  file.raw && getPreviewFileUrl(file.raw as File)
}
/** 文件数超出提示 */
const handleExceed = (): void => {
  ElMessage.error('最多只能上传一个文件！')
}
/** 上传错误处理 */
const handleUploadError = (): void => {
  fileLoading.value = false
}
// 文件上传方法
const handlePostFile = async (options: UploadRequestOptions) => {
  const { file, onProgress, onSuccess, onError } = options

  fileLoading.value = true
  try {
    // 上传文件
    const formData = new FormData()
    formData.append('file', file)
    const manualUrl = await uploadFile(formData)
    // 更新文件列表
    fileList.value = [
      {
        ...file,
        response: manualUrl,
        name: file.name,
        status: 'success',
        url: manualUrl,
        uid: file.uid || Date.now() + Math.random()
      }
    ]
    onSuccess(manualUrl)
    handleSubmitOperationReport(manualUrl)
  } catch (error: any) {
    onError(error)
    ElMessage.error('上传失败，请您重新上传！')
  } finally {
    fileLoading.value = false
  }
}
// 提交审核
const handleSubmitOperationReport = async (manualUrl = '') => {
  // 弹窗选择审批人
  const { reportId, templateId, prepareJson } = props.editInspectionplanParams
  const params: Recordable = {
    id: reportId,
    prepareJson: prepareJson,
    auditUserIds: [formData.value.inspectionAuditId],
    approveUserIds: [formData.value.inspectionApproveId],
    reportType: PressureReportType['INSPECTIONPLAN']
    // 检验方案,
    // reportUrl: uploadUrl,
  }
  if(manualUrl) params.manualUrl = manualUrl
  const submitRes = await BoilerTaskOrderApi.submitOpinionNoticeApproval(params)
  if (submitRes) {
    ElMessage.success('提交审核成功')
    handleCloseModal()
  }
}
const handleSubmitConfirm = () => {
  approvalUserVisible.value = false
  // if(props.isEdit === 'add'){
  //   fileList.value[0]?.url ? handleSubmitOperationReport(fileList.value[0].url) : uploadRef.value.submit()
  // } else {
  //   handleSubmitOperationReport()
  // }
  fileList.value[0]?.url ? handleSubmitOperationReport(fileList.value[0].url) : uploadRef.value.submit()
}
const handleSubmitBefore = async () => {

  try {
    await editSpreadRecordRef.value?.handleSave()
  } catch (error) {
    console.error('保存数据失败:', error)
    ElMessage.error('保存数据失败，请重试')
    return
  }

  // console.log(props.editInspectionplanParams, 'props.editInspectionplanParams')
  // if (props.isEdit === 'add' && !fileList.value.length) return ElMessage.error('请先上传方案文件')
  if (!fileList.value.length) return ElMessage.error('请先上传方案文件')
  getSchemeReviewerList()
}

// 关闭弹窗
const handleCloseModal = () => {
  visible.value = false
  emits('refresh')
}
const pdfContentWidth = ref(0)
const wrapperContainerRef = ref<HTMLDivElement | null>(null)
const handleWindowResize = debounce(() => {
  if(wrapperContainerRef.value){
    console.log('wrapperContainerRef.value:log', wrapperContainerRef.value)
    const currentWidth = wrapperContainerRef.value?.clientWidth
    pdfContentWidth.value = currentWidth > 950 ? 950 : currentWidth - 20
  }
}, 100)

const initData=ref<InitParams>(
  {
    templateId: '',
    refId: '',
    refName:'',
    insId:'',
    opType: 1, // 0:excel,1: pdf
    manualUrl: '',
  });
const editData=ref<InitParams>(
  {
    templateId: '',
    refId: '',
    refName:'',
    insId:'',
    opType: 0, // 0:excel,1: pdf
  });
const spreadRef=ref();
const editSpreadRecordRef=ref();
const saveSuccessRecord = async (data)=>{
  handleSuccess()
  showInlineEditRecord.value = false
}
const editPreview=()=>{

  editData.value.templateId = props.editInspectionplanParams.templateId;
  editData.value.refId = props.editInspectionplanParams.reportId;
  editData.value.opType = 0;

  setTimeout(()=>{
    editSpreadRecordRef.value?.reloadView();
  },50)

  console.log('editDataPreview', editData.value)
}
const initPreview=()=>{

  initData.value.templateId = props.editInspectionplanParams.templateId;
  initData.value.refId = props.editInspectionplanParams.reportId;
  initData.value.opType = 1;

  initData.value.manualUrl = props.inspectionplanDetail?.manualUrl;

  setTimeout(()=>{
    spreadRef.value?.reloadView();
  },50)

  console.log('initPreview', initData.value)
}

onMounted(()=>{
  handleWindowResize()
  // console.log('wrapperContainerHeight.value ', wrapperContainerHeight.value)
  window.addEventListener('resize', handleWindowResize)
  // initPreview()
  editPreview()
})
onUnmounted(() => {
  window.removeEventListener('resize', handleWindowResize)
})

</script>

<style lang="scss" scoped>
:deep(.app-container) {
  position: relative;
}

.check-record-wrapper {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 2000;

  :deep(.el-card__body) {
    display: flex;
    justify-content: space-between;
    align-items: stretch;
    height: calc(100% - 58px);
  }

  :deep(.spread-designer-container) {
    height: calc(
      100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - 64px
    );
    padding: 0;
    border: 1px solid var(--el-border-color);
    border-right-width: 0px;
  }

  .designer-inner {
    width: calc(100% - 440px);
    flex: 1;
    position: relative;
  }

  .operation-inner {
    display: flex;
    flex-direction: column;
    gap: 10px;
    height: 100%;
    flex-basis: 440px;
    padding: 7px 10px 20px 10px;
    border: 1px solid var(--el-border-color);
    background-color: #fff;
    box-sizing: border-box;
    overflow: hidden;

    .btn-list {
      padding: 5px 0 2px;
    }

    .version-box {
      padding: 8px 0 12px;
    }

    .operation-item {
      position: relative;
      // max-height: calc(100% / 3);
      overflow: hidden;

      .item-header {
        position: sticky;
        left: 0;
        top: 0;
        z-index: 1000;
        width: 100%;
        height: 28px;
        padding-left: 20px;
        font-size: 16px;
        line-height: 28px;
        color: #fff;
        background: #fff url(@/assets/imgs/pressure/my-task-detail-operation-bg.png) no-repeat left
          top;
        background-size: 100% 28px;
      }

      .item-content {
        // height: calc(100% - 48px);
        height: auto;
        padding: 10px 0;
        font-size: 14px;
        overflow-y: auto;
        overflow-x: hidden;
        box-sizing: content-box;

        .el-empty {
          width: 100%;
          height: 150px;
          padding: 0;
          box-sizing: border-box;
        }
      }

      &:last-child {
        // max-height: unset;
        // flex-grow: 1;
        flex: 1;

        .item-content {
          height: calc(100% - 48px);
        }
      }

      :deep(.smart-table-inner .toolbar) {
        margin: 0 !important;
      }

      .error-item {
        display: flex;
        align-items: center;
        padding: 7px 10px;
        color: #41475c;
        border: 1px solid var(--el-border-color);
        border-width: 1px 0 1px 0;
        background-color: #f5f5fa;

        .el-icon {
          margin-right: 6px;
        }

        &:nth-child(n + 1) {
          margin-top: -1px;
        }

        &:nth-child(even) {
          background-color: #fff;
        }
      }
    }
  }
}

.history-version-table {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  :deep(.smart-table-inner) {
    flex: 1;
    display: flex;
    flex-direction: column;
    // border: 1px solid red;
    overflow: hidden;

    .smart-table-table {
      flex: 1;
      overflow: hidden;

      .el-table {
        height: calc(100% - 52px);
      }
    }
  }
}
</style>
<style>
.docx-wrapper {
  background-color: #fff !important;
}
.docx-wrapper > section.docx {
  box-shadow: none !important;
}
</style>
