<template>
  <div>
    <!-- 调查表填报弹窗（单记录类型） -->
    <survey-form-dialog
      :visible.sync="surveyFormDialogVisible"
      :survey-data="{ ...currentSurveyRow, ...surveyDetailData }"
      :form-fields="formFields"
      :is-view-mode="isViewMode"
      :audited-unit-id="auditedUnitId"
      :request-type="1"
      :upload-id="
        currentSurveyRow && currentSurveyRow.id ? currentSurveyRow.id : uploadId
      "
      :survey-template-id="
        currentSurveyRow && currentSurveyRow.surveyTemplateId
          ? currentSurveyRow.surveyTemplateId
          : surveyTemplateId
      "
      :catalog-id="catalogId"
      :task-id="taskId"
      @save="handleSurveyFormSave"
      @refresh="handleRefresh"
    />

    <!-- 固定表填报弹窗 -->
    <fixed-table-dialog
      :visible.sync="fixedTableDialogVisible"
      :survey-data="{ ...currentSurveyRow, fixedHeaders }"
      :table-items="tableItems"
      :audit-periods="auditPeriods"
      :project-audit-periods="auditPeriods"
      :project-audit-period="auditPeriod"
      :is-view-mode="isViewMode"
      :request-type="1"
      :audited-unit-id="auditedUnitId"
      :upload-id="
        currentSurveyRow && currentSurveyRow.id ? currentSurveyRow.id : uploadId
      "
      :survey-template-id="
        currentSurveyRow && currentSurveyRow.surveyTemplateId
          ? currentSurveyRow.surveyTemplateId
          : surveyTemplateId
      "
      :catalog-id="catalogId"
      :task-id="taskId"
      @save="handleFixedTableSave"
      @refresh="handleRefresh"
    />

    <!-- 动态表填报弹窗 -->
    <dynamic-table-dialog
      :key="dynamicDialogKey"
      :visible.sync="dynamicTableDialogVisible"
      :survey-data="currentSurveyRow"
      :table-data="dynamicTableData"
      :table-items="tableItems"
      :is-view-mode="isViewMode"
      :request-type="1"
      :audited-unit-id="auditedUnitId"
      :upload-id="
        currentSurveyRow && (currentSurveyRow.uploadId || currentSurveyRow.id)
          ? currentSurveyRow.uploadId || currentSurveyRow.id
          : uploadId
      "
      :catalog-id="catalogId"
      :survey-template-id="
        currentSurveyRow && currentSurveyRow.surveyTemplateId
          ? currentSurveyRow.surveyTemplateId
          : surveyTemplateId
      "
      @save="handleDynamicTableSave"
      @refresh="handleRefresh"
    />

    <el-table
      style="width: 100%; margin-top: 20px"
      :data="paginatedData"
      border
      size="medium"
    >
      <!-- 序号列 -->
      <el-table-column prop="index" label="序号" width="60" align="center">
        <template slot-scope="scope">
          {{ scope.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column label="成本调查表" min-width="220" align="center">
        <template slot-scope="scope">
          <span
            :style="{
              color: scope.row.isDisabled ? '#909399' : '#409EFF',
              cursor: scope.row.isDisabled ? 'default' : 'pointer',
            }"
            @click="
              !scope.row.isDisabled && $emit('handle-survey-click', scope.row)
            "
          >
            {{ scope.row.name }}
          </span>
        </template>
      </el-table-column>

      <!-- 资料类型列 -->
      <el-table-column
        prop="dataType"
        label="资料类型"
        width="120"
        align="center"
      ></el-table-column>

      <!-- 表格类型列 -->
      <el-table-column
        prop="tableType"
        label="表格类型"
        width="120"
        align="center"
      ></el-table-column>

      <!-- 是否必填列 -->
      <el-table-column
        prop="isRequired"
        label="是否必填"
        width="100"
        align="center"
      >
        <template slot-scope="scope">
          <span>
            {{
              scope.row.isRequired === '是' ||
              scope.row.isRequired === '1' ||
              scope.row.isRequired === 1
                ? '是'
                : '否'
            }}
          </span>
        </template>
      </el-table-column>

      <!-- 是否上传列（红色“未上传”、绿色“已上传”） -->
      <el-table-column label="是否上传" width="100" align="center">
        <template slot-scope="scope">
          <span
            :style="{
              color: scope.row.isUploaded === true ? '#67c23a' : '#f56c6c',
            }"
          >
            {{ scope.row.isUploaded === true ? '已上传' : '未上传' }}
          </span>
        </template>
      </el-table-column>
      <el-table-column label="初审结果" width="100" align="center">
        <template slot-scope="scope">
          <span
            :class="{
              'result-pending':
                !scope.row.auditedStatus || scope.row.auditedStatus === '0',
              'result-pass': scope.row.auditedStatus === '1',
              'result-fail': scope.row.auditedStatus === '2',
            }"
          >
            {{
              !scope.row.auditedStatus || scope.row.auditedStatus === '0'
                ? '未审核'
                : scope.row.auditedStatus === '1'
                ? '通过'
                : '不通过'
            }}
          </span>
        </template>
      </el-table-column>
      <!-- 操作列（根据“表格类型”显示不同按钮） -->
      <el-table-column label="操作" width="320" align="center">
        <template slot-scope="scope">
          <!-- 在线填报：所有类型均显示 -->
          <el-button
            type="text"
            size="small"
            :disabled="isViewMode"
            @click="handleOnlineFillClick(scope.row)"
          >
            在线填报
          </el-button>

          <!-- 动态表：数据下载、数据上传 -->
          <template v-if="scope.row.tableType === '动态表'">
            <el-button
              type="text"
              size="small"
              :disabled="isViewMode"
              @click="handleDataDownload(scope.row)"
            >
              数据下载
            </el-button>
            <el-button
              type="text"
              size="small"
              :disabled="isViewMode"
              @click="handleDataUpload(scope.row)"
            >
              数据上传
            </el-button>
          </template>

          <!-- 固定表：模版下载、数据上传 -->
          <template v-else-if="scope.row.tableType === '固定表'">
            <el-button
              type="text"
              size="small"
              :disabled="isViewMode"
              @click="handleDataDownload(scope.row)"
            >
              模版下载
            </el-button>
            <el-button
              type="text"
              size="small"
              :disabled="isViewMode"
              @click="handleDataUpload(scope.row)"
            >
              数据上传
            </el-button>
          </template>

          <!-- 单记录：仅显示在线填报（上面已显示），不再追加其他按钮 -->
        </template>
      </el-table-column>
    </el-table>
    <input
      ref="dynamicUploadInput"
      type="file"
      accept=".xls,.xlsx"
      style="display: none"
      @change="handleDynamicUploadChange"
    />
    <el-pagination
      background
      layout="total, sizes, prev, pager, next"
      :current-page="pagination.currentPage"
      :page-sizes="[10, 20, 30, 50]"
      :page-size="pagination.pageSize"
      :total="pagination.total"
      style="margin-top: 20px; text-align: right"
      @current-change="$emit('handle-page-change', $event)"
      @size-change="$emit('handle-size-change', $event)"
    />
  </div>
</template>

<script>
  import SurveyFormDialog from './SurveyFormDialog.vue'
  import FixedTableDialog from './FixedTableDialog.vue'
  import DynamicTableDialog from './DynamicTableDialog.vue'
  import {
    getSingleRecordSurveyList,
    getSurveyDetail,
    getDynamicTableData,
    downloadTemplate,
    importData,
  } from '@/api/audit/survey'
  import { getListBySurveyTemplateIdAndVersion } from '@/api/costSurveyTemplateHeaders'

  export default {
    name: 'CostSurveyTab',
    components: {
      SurveyFormDialog,
      FixedTableDialog,
      DynamicTableDialog,
    },
    props: {
      paginatedData: {
        type: Array,
        default: () => [],
      },
      pagination: {
        type: Object,
        default: () => ({ currentPage: 1, pageSize: 10, total: 0 }),
      },
      isViewMode: {
        type: Boolean,
        default: false,
      },
      // 被监审单位ID
      auditedUnitId: {
        type: String,
        default: '',
      },
      // 上传记录ID
      uploadId: {
        type: String,
        default: '',
      },
      // 成本调查表模板ID
      surveyTemplateId: {
        type: String,
        default: '',
      },
      // 目录ID
      catalogId: {
        type: String,
        default: '',
      },
      // 任务ID（用于上传）
      taskId: {
        type: [String, Number],
        default: '',
      },
      // 监审期间（从立项信息中获取）
      auditPeriod: {
        type: [String, Array],
        default: null,
      },
    },
    data() {
      return {
        surveyFormDialogVisible: false,
        fixedTableDialogVisible: false,
        dynamicTableDialogVisible: false,
        currentSurveyRow: null,
        // 表单字段配置（可以从后台获取，或通过 props 传入）
        formFields: [],
        // 表单详情数据（用于回显）
        surveyDetailData: {},
        // 固定表数据配置
        tableItems: [],
        // 监审期间（年份数组）
        auditPeriods: [],
        // 动态表数据
        dynamicTableData: [],
        dynamicDialogKey: 0,
        dynamicTableLoading: false,
        fixedHeaders: null,
        // 上传相关
        pendingDynamicRow: null,
      }
    },
    watch: {
      auditPeriod: {
        immediate: true,
        deep: true,
        handler() {
          this.syncAuditPeriodsFromProp()
        },
      },
    },
    mounted() {
      // 表单字段配置在打开弹窗时动态加载，不需要在 mounted 中初始化
      this.syncAuditPeriodsFromProp()
    },
    methods: {
      // 同步并规范化来自 props 的监审期间到本地数组
      syncAuditPeriodsFromProp() {
        const input = this.auditPeriod
        if (!input) {
          this.auditPeriods = []
          return
        }
        if (Array.isArray(input)) {
          this.auditPeriods = input.map((p) => String(p))
          return
        }
        const str = String(input).trim()
        if (!str) {
          this.auditPeriods = []
          return
        }
        if (str.includes(',')) {
          this.auditPeriods = str
            .split(',')
            .map((s) => s.trim())
            .filter(Boolean)
          return
        }
        if (str.includes('-')) {
          const parts = str.split('-')
          if (parts.length === 2) {
            const start = parseInt(parts[0].trim())
            const end = parseInt(parts[1].trim())
            const years = []
            if (!isNaN(start) && !isNaN(end) && end >= start) {
              for (let y = start; y <= end; y++) years.push(String(y))
            }
            this.auditPeriods = years
            return
          }
        }
        this.auditPeriods = [str]
      },
      // 处理在线填报点击
      async handleOnlineFillClick(row) {
        this.currentSurveyRow = row
        // 重置详情数据
        this.surveyDetailData = {}

        // 如果表格类型是"单记录"，弹出调查表填报弹窗
        if (row.tableType === '单记录') {
          console.log(this.auditedUnitId, 'this.auditedUnitId')
          // 如果该行有 id，先调用接口获取详情数据
          if (row.id && this.auditedUnitId) {
            try {
              const params = {
                uploadId: row.id,
                auditedUnitId: this.auditedUnitId,
                type: 1,
              }
              const res = await getSurveyDetail(params)
              console.log('单记录详情数据', res)
              if (res && res.code === 200 && res.value) {
                // 将详情数据转换为表单数据格式
                // 接口返回的数据可能是数组格式 [{rowid: 'xxx', rkey: 'xxx', rvalue: 'xxx'}, ...]
                // 需要转换为 {rowid: 'rvalue', ...} 的格式
                const detailData = {}
                if (Array.isArray(res.value)) {
                  res.value.forEach((item) => {
                    if (item.rowid && item.rvalue !== undefined) {
                      detailData[item.rowid] = item.rvalue
                    }
                  })
                } else if (res.value) {
                  // 如果不是数组，可能是对象格式，直接使用
                  Object.assign(detailData, res.value)
                }
                this.surveyDetailData = detailData
                console.log('转换后的详情数据', this.surveyDetailData)
              }
            } catch (err) {
              console.error('获取单记录详情失败', err)
            }
          }
          // 调用接口获取单记录表单字段配置（详情数据已准备好）
          await this.initFormFields()
          // 接口调用完成后会自动打开弹窗（在 initFormFields 中处理）
        } else if (row.tableType === '固定表') {
          // 如果表格类型是"固定表"，弹出固定表填报弹窗
          // 调用接口获取固定表配置
          await this.initFixedTableData()
          // 接口调用完成后会自动打开弹窗（在 initFixedTableData 中处理）
        } else if (row.tableType === '动态表') {
          // 如果表格类型是"动态表"，弹出动态表填报弹窗
          this.resetDynamicDialogState()
          await this.initDynamicTableData()
        } else {
          // 其他类型，触发原有事件
          this.$emit('handle-online-fill', row)
        }
      },
      // 处理调查表保存
      handleSurveyFormSave(formData) {
        // 可以将保存的数据传递给父组件
        this.$emit('handle-survey-form-save', {
          row: this.currentSurveyRow,
          formData: formData,
        })
      },
      // 处理刷新事件
      handleRefresh() {
        // 触发父组件的刷新事件
        this.$emit('handle-survey-form-save', {
          row: this.currentSurveyRow,
          formData: {},
        })
      },
      // 处理固定表保存
      handleFixedTableSave(tableData) {
        // 可以将保存的数据传递给父组件
        this.$emit('handle-fixed-table-save', {
          row: this.currentSurveyRow,
          tableData: tableData,
        })
      },
      // 处理动态表保存
      handleDynamicTableSave(tableData) {
        // 将保存的数据传递给父组件
        this.$emit('handle-dynamic-table-save', {
          row: this.currentSurveyRow,
          tableData: tableData,
        })
        // 触发刷新事件
        this.handleRefresh()
      },
      // 触发动态表数据上传
      handleDataUpload(row) {
        if (this.isViewMode) return
        this.pendingDynamicRow = row || null
        this.$nextTick(() => {
          const input = this.$refs.dynamicUploadInput
          if (input) {
            input.value = ''
            input.click()
          }
        })
      },
      // 文件选择后上传
      async handleDynamicUploadChange(e) {
        const files = e && e.target && e.target.files
        if (!files || !files.length || !this.pendingDynamicRow) return
        const file = files[0]
        const row = this.pendingDynamicRow
        // 参数收集
        const surveyTemplateId =
          (row && (row.surveyTemplateId || row.templateId)) ||
          this.surveyTemplateId ||
          ''
        const taskId = (row && row.taskId) || this.taskId || ''
        const materialId = row && (row.materialId || row.materialID || row.id)
        const periodRecordId =
          row && (row.periodRecordId || row.uploadId || row.id)
        if (!surveyTemplateId || !taskId) {
          this.$message &&
            this.$message.warning &&
            this.$message.warning('缺少必要参数，无法上传')
          return
        }
        const formData = new FormData()
        formData.append('file', file)
        formData.append('surveyTemplateId', surveyTemplateId)
        formData.append('taskId', taskId)
        if (materialId) formData.append('materialId', materialId)
        if (periodRecordId) formData.append('periodRecordId', periodRecordId)
        formData.append('type', '1')

        let loading
        try {
          loading = this.$loading({
            lock: true,
            text: '数据上传中...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)',
          })
          await importData(formData)
          this.$message &&
            this.$message.success &&
            this.$message.success('数据上传成功')
          // 上传成功后触发刷新
          this.$emit('handle-dynamic-table-save', { row, tableData: {} })
          this.handleRefresh()
        } catch (err) {
          console.error('数据上传失败:', err)
        } finally {
          if (loading && loading.close) loading.close()
          this.pendingDynamicRow = null
          if (this.$refs.dynamicUploadInput)
            this.$refs.dynamicUploadInput.value = ''
        }
      },
      // 动态表-数据下载
      async handleDataDownload(row) {
        try {
          const loading = this.$loading({
            lock: true,
            text: '数据下载中...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)',
          })
          // 取 surveyTemplateId 与 versionId
          const surveyTemplateId =
            (row && (row.surveyTemplateId || row.templateId)) ||
            this.surveyTemplateId ||
            ''
          const versionId =
            (row && (row.versionId || row.version || row.templateVersionId)) ||
            ''
          // if (!surveyTemplateId || !versionId) {
          //   loading.close()
          //   this.$message &&
          //     this.$message.warning &&
          //     this.$message.warning('缺少模板或版本信息，无法下载')
          //   return
          // }
          const params = { surveyTemplateId, versionId, type: 1 }
          const res = await downloadTemplate(params)
          loading.close()
          // 处理响应数据（可能是 axios 响应或直接 Blob）
          const headers = (res && res.headers) || {}
          const contentDisposition =
            headers['content-disposition'] || headers['Content-Disposition']
          let fileName =
            this.extractFileNameFromHeader(contentDisposition) ||
            `${row.name || '数据'}.xlsx`
          if (!/\.[a-zA-Z0-9]+$/.test(fileName)) {
            fileName += '.xlsx'
          }
          const blobData = (res && res.data) || res
          const blob =
            blobData instanceof Blob ? blobData : new Blob([blobData])
          const url = window.URL.createObjectURL(blob)
          const link = document.createElement('a')
          link.style.display = 'none'
          link.href = url
          link.download = fileName
          document.body.appendChild(link)
          link.click()
          document.body.removeChild(link)
          window.URL.revokeObjectURL(url)
          this.$message &&
            this.$message.success &&
            this.$message.success('开始下载文件')
        } catch (e) {
          console.error('数据下载失败: ', e)
        }
      },
      extractFileNameFromHeader(contentDisposition) {
        if (!contentDisposition) return ''
        const match = /filename[^;=\n]*=((['"])?.*?\2|[^;\n]*)/i.exec(
          contentDisposition
        )
        if (match && match[1]) {
          try {
            return decodeURIComponent(match[1].replace(/['"]/g, ''))
          } catch (e) {
            return match[1].replace(/['"]/g, '')
          }
        }
        return ''
      },
      // 初始化动态表数据
      async initDynamicTableData() {
        try {
          this.dynamicTableLoading = true
          const uploadId =
            (this.currentSurveyRow &&
              (this.currentSurveyRow.uploadId || this.currentSurveyRow.id)) ||
            this.uploadId ||
            ''
          const auditedUnitId =
            this.auditedUnitId ||
            (this.currentSurveyRow && this.currentSurveyRow.auditedUnitId) ||
            ''
          const catalogId =
            (this.currentSurveyRow && this.currentSurveyRow.catalogId) ||
            this.catalogId ||
            ''
          const surveyTemplateId =
            (this.currentSurveyRow && this.currentSurveyRow.surveyTemplateId) ||
            this.surveyTemplateId ||
            ''

          const params = {
            uploadId,
            auditedUnitId,
            catalogId,
            surveyTemplateId,
            type: 1,
          }

          const res = await getDynamicTableData(params)
          if (res && res.code === 200) {
            const records = res.value?.records || res.value || []
            this.dynamicTableData = Array.isArray(records) ? records : []
          } else {
            // 接口调用失败，使用当前行的动态表数据或空数组
            this.dynamicTableData =
              this.currentSurveyRow?.dynamicTableData || []
          }

          // 初始化表格项配置（用于详情/编辑时显示表单）
          if (
            this.currentSurveyRow &&
            this.currentSurveyRow.tableItems &&
            this.currentSurveyRow.tableItems.length > 0
          ) {
            this.tableItems = this.currentSurveyRow.tableItems
          } else {
            this.tableItems = this.getMockTableItems()
          }

          this.dynamicTableDialogVisible = true
        } catch (error) {
          console.error('获取动态表数据失败', error)
          // 出错时使用当前行的动态表数据或空数组
          this.dynamicTableData = this.currentSurveyRow?.dynamicTableData || []
          this.tableItems =
            this.currentSurveyRow?.tableItems || this.getMockTableItems()
          // 出错时也打开弹窗
          this.dynamicTableDialogVisible = true
        } finally {
          this.dynamicTableLoading = false
        }
      },
      // 初始化表单字段配置
      async initFormFields() {
        // 如果是单记录类型，调用接口获取表单字段配置（包含校验规则）
        if (
          this.currentSurveyRow &&
          this.currentSurveyRow.tableType === '单记录' &&
          this.currentSurveyRow.surveyTemplateId
        ) {
          try {
            const params = {
              surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
              type: 1,
            }
            // 调用 getListBySurveyTemplateIdAndVersion 获取完整的字段配置（包含校验规则）
            const res = await getListBySurveyTemplateIdAndVersion(params)
            console.log('单记录表单字段配置（含校验规则）', res)
            if (res && res.code === 200) {
              let mapped = []
              if (Array.isArray(res.value)) {
                // 数组格式：直接映射每个字段（包含完整的校验规则）
                mapped = res.value
                  .map((item, index) =>
                    this.mapApiFieldToFormField(item, index)
                  )
                  .filter(Boolean)
              } else if (res.value && typeof res.value === 'object') {
                // 对象格式：从 fixedFields 和 fixedFieldids 解析（兼容旧格式）
                const { fixedFields, fixedFieldids } = res.value
                if (fixedFields && fixedFieldids) {
                  const labels = fixedFields
                    .split(',')
                    .map((item) => item.trim())
                  const ids = fixedFieldids
                    .split(',')
                    .map((item) => item.trim())
                  mapped = labels.map((label, index) => ({
                    prop: ids[index] || `field_${index}`,
                    label: label,
                    type: 'input',
                    colSpan: 12,
                    placeholder: `请输入${label}`,
                    rules: [],
                    defaultValue: '',
                    disabled: false,
                    clearable: true,
                    multiple: false,
                    required: false,
                  }))
                }
              }

              if (mapped.length > 0) {
                // 使用包含完整校验规则的字段配置
                this.formFields = mapped
                console.log(
                  '转换后的表单字段配置（含校验规则）',
                  this.formFields
                )
              } else {
                // 如果没有数据，使用默认配置
                this.formFields = this.getMockFormFields()
              }
            } else {
              // 接口返回失败，使用默认配置
              this.formFields = this.getMockFormFields()
            }
            // 打开弹窗
            this.surveyFormDialogVisible = true
          } catch (err) {
            console.error('获取单记录表单字段配置失败', err)
            // 出错时使用默认配置
            this.formFields = this.getMockFormFields()
            this.surveyFormDialogVisible = true
          }
        } else if (this.currentSurveyRow && this.currentSurveyRow.formFields) {
          // 如果当前行有表单配置，则使用
          this.formFields = this.currentSurveyRow.formFields
          this.surveyFormDialogVisible = true
        } else {
          // 使用假数据作为测试（实际开发中应该从后台获取）
          this.formFields = this.getMockFormFields()
          this.surveyFormDialogVisible = true
        }
      },
      // 将 API 返回的字段数据映射为表单字段配置（包含校验规则）
      mapApiFieldToFormField(item, index = 0) {
        if (!item) return null
        const getVal = (keys, fallback) => {
          for (const key of keys) {
            if (
              key &&
              item[key] !== undefined &&
              item[key] !== null &&
              item[key] !== ''
            ) {
              return item[key]
            }
          }
          return fallback
        }
        const toBool = (value) => {
          if (value === undefined || value === null) return false
          if (typeof value === 'boolean') return value
          if (typeof value === 'number') return value === 1
          const str = String(value).trim().toLowerCase()
          return ['1', 'true', 'y', 'yes', '是'].includes(str)
        }
        const toNumber = (value) => {
          if (value === undefined || value === null || value === '')
            return undefined
          const num = Number(value)
          return Number.isNaN(num) ? undefined : num
        }
        const prop =
          getVal(
            [
              'fieldName',
              'field_name',
              'columnName',
              'column_name',
              'fieldCode',
            ],
            undefined
          ) || `field_${index}`
        const label =
          getVal(
            [
              'columnComment',
              'column_comment',
              'fieldCname',
              'field_cname',
              'fieldLabel',
              'field_label',
            ],
            prop
          ) || prop
        const columnType =
          (getVal(
            ['columnType', 'column_type', 'fieldType', 'field_type'],
            ''
          ) || '') + ''
        const columnTypeLower = columnType.toLowerCase()
        const totalLength = toNumber(
          getVal(
            ['fieldTypeLen', 'field_typelen', 'length', 'fieldLength'],
            undefined
          )
        )
        const decimalLength = toNumber(
          getVal(
            ['fieldTypeNointLen', 'field_typenointlen', 'scale'],
            undefined
          )
        )
        const isAuditPeriod = toBool(
          getVal(['isAuditPeriod', 'is_audit_period'], false)
        )
        const dictCode =
          getVal(
            [
              'dictCode',
              'dict_code',
              'dictId',
              'dictid',
              'dictType',
              'dict_type',
            ],
            ''
          ) || ''
        const optionsRaw = getVal(['options'], [])
        let options = []
        if (Array.isArray(optionsRaw)) {
          options = optionsRaw
        } else if (typeof optionsRaw === 'string' && optionsRaw.trim() !== '') {
          options = optionsRaw.split(',').map((value) => ({
            label: value.trim(),
            value: value.trim(),
          }))
        }
        let type = getVal(['componentType', 'type'], '')
        if (!type) {
          if (dictCode || options.length > 0) {
            type = 'select'
          } else if (
            columnTypeLower.includes('datetime') ||
            columnTypeLower.includes('timestamp') ||
            columnTypeLower.includes('date time')
          ) {
            type = 'datetime'
          } else if (columnTypeLower.includes('date')) {
            type = 'date'
          } else if (columnTypeLower.includes('year')) {
            type = 'year'
          } else if (
            columnTypeLower.includes('int') ||
            columnTypeLower.includes('number') ||
            columnTypeLower.includes('decimal') ||
            columnTypeLower.includes('float') ||
            columnTypeLower.includes('double')
          ) {
            type = 'number'
          } else {
            type = 'input'
          }
        }
        const required = toBool(
          getVal(['isRequired', 'is_required', 'required'], false)
        )
        const multiple = toBool(
          getVal(['isMultiple', 'is_multiple', 'multiple'], false)
        )
        const colSpan =
          toNumber(
            getVal(['colSpan', 'colspan', 'columnSpan', 'column_span'], 12)
          ) || 12
        const placeholder =
          getVal(
            ['placeholder', 'columnComment', 'column_comment'],
            undefined
          ) || (type === 'select' ? `请选择${label}` : `请输入${label}`)
        const defaultValue = getVal(
          ['defaultValue', 'default_value', 'defaultVal', 'default_val'],
          undefined
        )
        const precision = toNumber(
          getVal(
            ['fieldTypeNointLen', 'field_typenointlen', 'precision'],
            undefined
          )
        )
        const min = toNumber(getVal(['min'], undefined))
        const max = toNumber(getVal(['max'], undefined))
        const format = getVal(['format'], undefined)
        const valueFormat =
          getVal(['valueFormat', 'value_format'], undefined) ||
          (type === 'datetime'
            ? 'yyyy-MM-dd HH:mm:ss'
            : type === 'date'
            ? 'yyyy-MM-dd'
            : type === 'year'
            ? 'yyyy'
            : undefined)

        const formatLength = this.extractLengthFromFormat(format)
        const rules = this.buildFieldRules({
          type,
          label,
          required,
          totalLength,
          decimalLength,
          formatLength,
          format,
          isAuditPeriod,
        })

        return {
          prop,
          label,
          type,
          colSpan,
          placeholder,
          dictCode,
          dictType: dictCode,
          options,
          required,
          defaultValue,
          multiple,
          precision,
          min,
          max,
          format,
          valueFormat,
          totalLength,
          decimalLength,
          formatLength,
          rules, // 包含完整的校验规则
        }
      },
      // 从 format 中提取长度
      extractLengthFromFormat(format) {
        if (!format) return undefined
        const str = String(format).trim()
        if (!str) return undefined
        const match = str.match(/\d+/)
        if (match && match[0]) {
          const len = Number(match[0])
          return Number.isNaN(len) ? undefined : len
        }
        return undefined
      },
      // 构建字段校验规则
      buildFieldRules(meta) {
        const {
          type,
          label,
          required,
          totalLength,
          decimalLength,
          formatLength,
          format,
          isAuditPeriod,
        } = meta || {}
        const rules = []
        const trigger = type === 'select' ? 'change' : 'blur'
        if (required) {
          rules.push({
            required: true,
            message: `${type === 'select' ? '请选择' : '请输入'}${label}`,
            trigger,
          })
        }
        const inputMaxLength = formatLength || totalLength
        if (type === 'input' && inputMaxLength) {
          rules.push({
            validator: (_, value, callback) => {
              if (value === undefined || value === null || value === '') {
                callback()
                return
              }
              const str = String(value)
              if (str.length > inputMaxLength) {
                callback(
                  new Error(`${label}长度不能超过${inputMaxLength}个字符`)
                )
              } else {
                callback()
              }
            },
            trigger: 'blur',
          })
        }
        const numberTotal = totalLength || formatLength
        if (type === 'number') {
          rules.push({
            validator: (_, value, callback) => {
              if (value === undefined || value === null || value === '') {
                callback()
                return
              }
              if (Number.isNaN(Number(value))) {
                callback(new Error(`${label}必须为数字`))
                return
              }
              const pure = String(value).replace('-', '')
              if (numberTotal && pure.replace('.', '').length > numberTotal) {
                callback(new Error(`${label}总位数不能超过${numberTotal}`))
                return
              }
              if (decimalLength !== undefined && decimalLength !== null) {
                const decimals = pure.split('.')[1] || ''
                if (decimals.length > decimalLength) {
                  callback(
                    new Error(`${label}小数位不能超过${decimalLength}位`)
                  )
                  return
                }
              }
              callback()
            },
            trigger: 'blur',
          })
        }
        if (type === 'datetime' || type === 'date') {
          if (format) {
            rules.push({
              validator: (_, value, callback) => {
                if (value === undefined || value === null || value === '') {
                  callback()
                  return
                }
                callback()
              },
              trigger: 'change',
            })
          }
        }
        if (type === 'year' || isAuditPeriod) {
          rules.push({
            validator: (_, value, callback) => {
              if (value === undefined || value === null || value === '') {
                callback()
                return
              }
              const pattern = /^\d{4}$/
              if (!pattern.test(String(value))) {
                callback(new Error(`${label}必须是四位年份`))
              } else {
                callback()
              }
            },
            trigger: 'change',
          })
        }
        return rules
      },
      // 获取假数据表单字段配置（用于测试）
      getMockFormFields() {
        // return [
        //   {
        //     prop: 'institutionName',
        //     label: '机构名称',
        //     type: 'input',
        //     colSpan: 12,
        //     defaultValue: '幼儿园基本情况',
        //     placeholder: '请输入机构名称',
        //     required: true,
        //   },
        //   {
        //     prop: 'institutionNature',
        //     label: '机构性质',
        //     type: 'select',
        //     colSpan: 12,
        //     dictType: 'institutionNature', // 字典类型
        //     defaultValue: '公办',
        //     placeholder: '请选择机构性质',
        //     required: true,
        //     clearable: true,
        //   },
        //   {
        //     prop: 'institutionLevel',
        //     label: '机构评定等级',
        //     type: 'select',
        //     colSpan: 12,
        //     dictType: 'institutionLevel', // 字典类型
        //     defaultValue: '省一级',
        //     placeholder: '请选择机构评定等级',
        //     required: true,
        //     clearable: true,
        //   },
        //   {
        //     prop: 'educationMode',
        //     label: '机构办学方式',
        //     type: 'select',
        //     colSpan: 12,
        //     dictType: 'educationMode', // 字典类型
        //     defaultValue: '全日制',
        //     placeholder: '请选择机构办学方式',
        //     required: true,
        //     clearable: true,
        //   },
        //   {
        //     prop: 'institutionAddress',
        //     label: '机构地址',
        //     type: 'input',
        //     colSpan: 12,
        //     placeholder: '请输入机构地址',
        //     required: true,
        //   },
        //   {
        //     prop: 'formFiller',
        //     label: '机构填表人',
        //     type: 'input',
        //     colSpan: 12,
        //     placeholder: '请输入机构填表人',
        //     required: true,
        //   },
        //   {
        //     prop: 'financialManager',
        //     label: '机构财务负责人',
        //     type: 'input',
        //     colSpan: 12,
        //     placeholder: '请输入机构财务负责人',
        //     required: true,
        //   },
        //   {
        //     prop: 'contactPhone',
        //     label: '机构联系电话',
        //     type: 'input',
        //     colSpan: 12,
        //     placeholder: '请输入机构联系电话',
        //     required: true,
        //     rules: [
        //       {
        //         required: true,
        //         message: '请输入机构联系电话',
        //         trigger: 'blur',
        //       },
        //       {
        //         pattern: /^1[3-9]\d{9}$/,
        //         message: '请输入正确的手机号码',
        //         trigger: 'blur',
        //       },
        //     ],
        //   },
        // ]
      },
      // 初始化固定表数据
      async initFixedTableData() {
        // 如果是固定表类型，调用接口获取固定表配置
        if (
          this.currentSurveyRow &&
          this.currentSurveyRow.tableType === '固定表' &&
          this.currentSurveyRow.surveyTemplateId
        ) {
          try {
            const params = {
              surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
              type: 1,
            }
            const res = await getSingleRecordSurveyList(params)

            console.log('固定表配置数据', res)
            if (res && res.code === 200 && res.value) {
              // 将接口返回的数据转换为固定表配置格式
              // 固定表使用 itemlist，不使用 fixedFields 和 fixedFieldids
              const { itemlist } = res.value
              console.log('itemlist', itemlist)
              // 如果有 itemlist，使用 itemlist 作为表格项配置
              if (itemlist && Array.isArray(itemlist) && itemlist.length > 0) {
                this.tableItems = itemlist.map((item, index) => ({
                  id: item.id || item.itemId || '',
                  rowid: item.rowid || item.id || item.itemId || '', // rowid 用于父子关系
                  seq: item.序号, // 序号就是序号
                  itemName: item.项目 || '', // 项目就是项目
                  unit: item.unit || '', // 单位是 unit
                  isCategory: item.isCategory || false,
                  categorySeq: item.categorySeq || '',
                  categoryId: item.categoryId || '',
                  parentid:
                    item.parentid !== undefined
                      ? item.parentid
                      : item.parentId !== undefined
                      ? item.parentId
                      : '-1', // 父项ID，默认为 '-1'（父项）
                  validateRules: item.validateRules || {},
                  linkageRules: item.linkageRules || {},
                  children: item.children || [],
                  ...item, // 保留其他字段
                }))
              } else {
                // 如果没有 itemlist，使用假数据
                this.tableItems = this.getMockTableItems()
              }
            } else {
              // 接口返回失败，使用默认配置
              this.tableItems = this.getMockTableItems()
            }
          } catch (err) {
            console.error('获取固定表配置失败', err)
            // 出错时使用默认配置
            this.tableItems = this.getMockTableItems()
          }
        } else if (this.currentSurveyRow && this.currentSurveyRow.tableItems) {
          // 如果当前行有表格配置，则使用
          this.tableItems = this.currentSurveyRow.tableItems
        } else {
          // 使用假数据作为测试（实际开发中应该从后台获取）
          this.tableItems = this.getMockTableItems()
        }

        // 初始化监审期间（从立项信息中获取）
        if (this.auditPeriod) {
          // 如果传入了监审期间，使用传入的值
          if (Array.isArray(this.auditPeriod)) {
            this.auditPeriods = this.auditPeriod.map((p) => String(p))
          } else {
            this.auditPeriods = this.parseAuditPeriod(this.auditPeriod)
          }
        } else if (this.currentSurveyRow && this.currentSurveyRow.auditPeriod) {
          // 如果当前行有监审期间，使用当前行的
          this.auditPeriods = this.parseAuditPeriod(
            this.currentSurveyRow.auditPeriod
          )
        } else {
          // 默认使用最近3年
          const currentYear = new Date().getFullYear()
          this.auditPeriods = [
            String(currentYear - 2),
            String(currentYear - 1),
            String(currentYear),
          ]
        }

        // 额外拉取表头/规则信息，并透传给弹窗
        try {
          const headerRes = await getListBySurveyTemplateIdAndVersion({
            surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
            type: 1,
          })

          if (headerRes && headerRes.code === 200) {
            this.fixedHeaders = headerRes.value || null
          } else {
            this.fixedHeaders = null
          }
        } catch (e) {
          this.fixedHeaders = null
        }

        // 打开弹窗
        this.fixedTableDialogVisible = true
      },
      // 解析监审期间字符串（如 "2022,2023,2024" 或 "2022-2024"）
      parseAuditPeriod(periodStr) {
        if (!periodStr) return []
        if (periodStr.includes(',')) {
          return periodStr.split(',').map((p) => p.trim())
        }
        if (periodStr.includes('-')) {
          const parts = periodStr.split('-')
          if (parts.length === 2) {
            const start = parseInt(parts[0].trim())
            const end = parseInt(parts[1].trim())
            const years = []
            for (let year = start; year <= end; year++) {
              years.push(String(year))
            }
            return years
          }
        }
        return [String(periodStr)]
      },
      // 获取假数据表格配置（用于测试）
      getMockTableItems() {
        return [
          {
            id: '1',
            itemName: '班级数',
            unit: '个',
            isCategory: false,
            seq: 1,
            validateRules: {
              required: true,
              type: 'number',
              min: 0,
            },
          },
          {
            id: '2',
            itemName: '幼儿学生人数',
            unit: '人',
            isCategory: false,
            seq: 2,
            validateRules: {
              required: true,
              type: 'number',
              min: 0,
            },
          },
          {
            id: 'III',
            itemName: '在取做保职工总人数',
            unit: '人',
            isCategory: true,
            categorySeq: 'III',
            children: [
              {
                id: '3-1',
                itemName: '行政管理人员数',
                unit: '人',
                isCategory: false,
                categoryId: 'III',
                seq: 3,
                validateRules: {
                  required: true,
                  type: 'number',
                  min: 0,
                },
                linkageRules: {
                  parent: 'III',
                  relation: 'sum',
                },
              },
              {
                id: '3-2',
                itemName: '教师人数',
                unit: '人',
                isCategory: false,
                categoryId: 'III',
                seq: 4,
                validateRules: {
                  required: true,
                  type: 'number',
                  min: 0,
                },
                linkageRules: {
                  parent: 'III',
                  relation: 'sum',
                },
              },
              {
                id: '3-3',
                itemName: '保育员人数',
                unit: '人',
                isCategory: false,
                categoryId: 'III',
                seq: 5,
                validateRules: {
                  required: true,
                  type: 'number',
                  min: 0,
                },
                linkageRules: {
                  parent: 'III',
                  relation: 'sum',
                },
              },
              {
                id: '3-4',
                itemName: '医务人员',
                unit: '人',
                isCategory: false,
                categoryId: 'III',
                seq: 6,
                validateRules: {
                  required: true,
                  type: 'number',
                  min: 0,
                },
                linkageRules: {
                  parent: 'III',
                  relation: 'sum',
                },
              },
              {
                id: '3-5',
                itemName: '工勤人员',
                unit: '人',
                isCategory: false,
                categoryId: 'III',
                seq: 7,
                validateRules: {
                  required: true,
                  type: 'number',
                  min: 0,
                },
                linkageRules: {
                  parent: 'III',
                  relation: 'sum',
                },
                children: [
                  {
                    id: '3-5-1',
                    itemName: '炊事员',
                    unit: '人',
                    isCategory: false,
                    categoryId: '3-5',
                    seq: 8,
                    validateRules: {
                      required: true,
                      type: 'number',
                      min: 0,
                    },
                    linkageRules: {
                      parent: '3-5',
                      relation: 'sum',
                    },
                  },
                  {
                    id: '3-5-2',
                    itemName: '司机',
                    unit: '人',
                    isCategory: false,
                    categoryId: '3-5',
                    seq: 9,
                    validateRules: {
                      required: true,
                      type: 'number',
                      min: 0,
                    },
                    linkageRules: {
                      parent: '3-5',
                      relation: 'sum',
                    },
                  },
                  {
                    id: '3-5-3',
                    itemName: '清洁工',
                    unit: '人',
                    isCategory: false,
                    categoryId: '3-5',
                    seq: 10,
                    validateRules: {
                      required: true,
                      type: 'number',
                      min: 0,
                    },
                    linkageRules: {
                      parent: '3-5',
                      relation: 'sum',
                    },
                  },
                ],
              },
              {
                id: '3-6',
                itemName: '其他人员',
                unit: '人',
                isCategory: false,
                categoryId: 'III',
                seq: 11,
                validateRules: {
                  required: true,
                  type: 'number',
                  min: 0,
                },
                linkageRules: {
                  parent: 'III',
                  relation: 'sum',
                },
              },
            ],
          },
        ]
      },
      resetDynamicDialogState() {
        this.dynamicTableDialogVisible = false
        this.dynamicTableData = []
        this.tableItems = []
        this.dynamicDialogKey = Date.now()
      },
    },
  }
</script>
