<template>
  <el-dialog
    title="调查表填报"
    :visible.sync="dialogVisible"
    width="90%"
    :close-on-click-modal="false"
    :show-close="true"
    append-to-body
    :modal="false"
    @close="handleClose"
  >
    <el-table
      :data="tableData"
      border
      style="width: 100%"
      :row-class-name="getRowClassName"
    >
      <!-- 序号列 -->
      <el-table-column prop="seq" label="序号" width="80" align="center">
        <template slot-scope="scope">
          <span>{{ scope.row.seq }}</span>
        </template>
      </el-table-column>

      <!-- 项目列（只读） -->
      <el-table-column
        prop="itemName"
        label="项目"
        min-width="200"
        align="left"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.isCategory" class="category-name">
            {{ scope.row.itemName }}
          </span>
          <span v-else>{{ scope.row.itemName }}</span>
        </template>
      </el-table-column>

      <!-- 单位列（只读） -->
      <el-table-column prop="unit" label="单位" width="100" align="center">
        <template slot-scope="scope">
          <span v-if="!scope.row.isCategory">{{ scope.row.unit }}</span>
        </template>
      </el-table-column>

      <!-- 指标编号（cellCode，只读） -->
      <el-table-column
        prop="cellCode"
        label="指标编号"
        width="120"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="!scope.row.isCategory">{{ scope.row.cellCode }}</span>
        </template>
      </el-table-column>

      <!-- 计算方式（calculationFormula，只读） -->
      <el-table-column
        prop="calculationFormula"
        label="计算方式"
        min-width="180"
        align="left"
      >
        <template slot-scope="scope">
          <span v-if="!scope.row.isCategory">
            {{ scope.row.calculationFormula }}
          </span>
        </template>
      </el-table-column>

      <!-- 动态年份列 -->
      <el-table-column
        v-for="year in yearColumns"
        :key="year"
        :label="`${year}年`"
        :prop="`year_${year}`"
        width="150"
        align="center"
      >
        <template slot-scope="scope">
          <el-input
            v-if="!scope.row.isCategory"
            v-model="scope.row[`year_${year}`]"
            :placeholder="`请输入${year}年数据`"
            :disabled="isViewMode"
            @blur="handleCellBlur(scope.row, year)"
            @input="handleCellInput(scope.row, year)"
          />
        </template>
      </el-table-column>

      <!-- 备注列 -->
      <el-table-column prop="remark" label="备注" min-width="150" align="left">
        <template slot-scope="scope">
          <el-input
            v-if="!scope.row.isCategory"
            v-model="scope.row.remark"
            placeholder="请输入备注"
            :disabled="isViewMode"
          />
        </template>
      </el-table-column>
    </el-table>

    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @click="handleSave">保存</el-button>
      <el-button @click="handleCancel">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
  import { Message } from 'element-ui'
  import { saveSingleRecordSurvey, getSurveyDetail } from '@/api/audit/survey'

  export default {
    name: 'FixedTableDialog',
    props: {
      visible: {
        type: Boolean,
        default: false,
      },
      surveyData: {
        type: Object,
        default: () => ({}),
      },
      // 表格数据配置
      // 格式: [
      //   {
      //     id: '1',
      //     itemName: '班级数',
      //     unit: '个',
      //     isCategory: false,
      //     parentId: null,
      //     categoryId: 'III',
      //     seq: 1,
      //     validateRules: {
      //       required: true,
      //       type: 'number',
      //       min: 0,
      //     },
      //     linkageRules: {
      //       parent: 'III',
      //       relation: 'sum',
      //     },
      //   },
      //   {
      //     id: 'III',
      //     itemName: '在取做保职工总人数',
      //     unit: '人',
      //     isCategory: true,
      //     categorySeq: 'III',
      //     children: [...],
      //   }
      // ]
      tableItems: {
        type: Array,
        default: () => [],
      },
      // 监审期间（年份数组）
      // 格式: ['2022', '2023', '2024']
      auditPeriods: {
        type: Array,
        default: () => [],
      },
      // 立项信息中的监审期间（优先使用）- 数组
      projectAuditPeriods: {
        type: Array,
        default: () => [],
      },
      // 立项信息中的监审期间（字符串，如 '2022,2023,2024' 或 '2022-2024'）
      projectAuditPeriod: {
        type: String,
        default: '',
      },
      // 是否查看模式
      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: '',
      },
      // 统一控制接口 type（1=成本调查表，2=报送资料）
      requestType: {
        type: [String, Number],
        default: 1,
      },
      // 任务ID
      taskId: {
        type: [String, Number],
        default: '',
      },
    },
    data() {
      return {
        dialogVisible: false,
        tableData: [],
        yearColumns: [],
        validationErrors: [],
        cellCodeIndex: {}, // cellCode -> row
        dependentsMap: {}, // cellCode -> Set(rows depending on it)
      }
    },
    watch: {
      visible: {
        async handler(newVal) {
          this.dialogVisible = newVal
          if (newVal) {
            // 先初始化表格数据
            this.initTableData()
            // 等待 DOM 更新后，如果有 uploadId，调用接口获取详情数据并回显
            await this.$nextTick()
            this.loadDetailData()
          }
        },
        immediate: true,
      },
      dialogVisible(newVal) {
        if (!newVal) {
          this.$emit('update:visible', false)
        }
      },
      tableItems: {
        handler() {
          if (this.dialogVisible) {
            this.initTableData()
          }
        },
        deep: true,
      },
      auditPeriods: {
        handler() {
          if (this.dialogVisible) {
            this.initYearColumns()
            this.initTableData()
          }
        },
        deep: true,
      },
      projectAuditPeriods: {
        handler() {
          if (this.dialogVisible) {
            this.initYearColumns()
            this.initTableData()
          }
        },
        deep: true,
      },
      projectAuditPeriod(newVal) {
        if (this.dialogVisible) {
          this.initYearColumns()
          this.initTableData()
        }
      },
    },
    mounted() {
      this.initYearColumns()
    },
    methods: {
      // 初始化年份列
      initYearColumns() {
        // 1) 优先使用立项信息中的监审期间（数组）
        if (this.projectAuditPeriods && this.projectAuditPeriods.length > 0) {
          this.yearColumns = this.projectAuditPeriods.map((period) => {
            if (typeof period === 'string' && period.includes('-')) {
              return period.split('-')[0]
            }
            return String(period)
          })
        } else if (this.projectAuditPeriod) {
          // 2) 立项信息中的监审期间（字符串）
          const periods = this.parseAuditPeriod(this.projectAuditPeriod)
          this.yearColumns = periods
        } else if (this.auditPeriods && this.auditPeriods.length > 0) {
          // 3) 组件入参的监审期间（数组）
          // 如果传入了监审期间，使用监审期间
          this.yearColumns = this.auditPeriods.map((period) => {
            // 如果是日期格式，提取年份
            if (typeof period === 'string' && period.includes('-')) {
              return period.split('-')[0]
            }
            return String(period)
          })
        } else if (this.surveyData && this.surveyData.auditPeriod) {
          // 如果从 surveyData 中获取监审期间
          const periods = this.parseAuditPeriod(this.surveyData.auditPeriod)
          this.yearColumns = periods
        } else {
          // 默认使用最近3年
          const currentYear = new Date().getFullYear()
          this.yearColumns = [
            String(currentYear - 2),
            String(currentYear - 1),
            String(currentYear),
          ]
        }
      },
      // 解析监审期间字符串（如 "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)]
      },
      // 初始化表格数据
      initTableData() {
        console.log(this.isViewMode, '只读')
        if (!this.tableItems || this.tableItems.length === 0) {
          // 如果没有传入数据，使用假数据
          this.tableData = this.getMockTableData()
          return
        }

        // 根据 parentid 关系排列：parentid 为 '-1' 的是父项，子项的 parentid 等于父项的 rowid/id
        const flatData = []
        const processedIds = new Set()

        // 先处理所有父项（parentid 为 '-1'）
        this.tableItems.forEach((item) => {
          const parentid = item.parentid
          const rowid = item.rowid || item.id

          if (parentid === '-1' || parentid === -1) {
            const rowData = this.createRowData(item, false, rowid)
            flatData.push(rowData)
            processedIds.add(rowid)
          }
        })

        // 再处理所有子项，紧跟在父项后面，按正序排列
        // 先收集所有子项，按序号或顺序排序
        const childItems = this.tableItems.filter((item) => {
          const rowid = item.rowid || item.id
          const parentid = item.parentid
          return (
            !processedIds.has(rowid) && parentid !== '-1' && parentid !== -1
          )
        })

        // 对子项按序号正序排序
        childItems.sort((a, b) => {
          const seqA =
            a.seq !== undefined
              ? typeof a.seq === 'number'
                ? a.seq
                : parseInt(a.seq) || 0
              : 0
          const seqB =
            b.seq !== undefined
              ? typeof b.seq === 'number'
                ? b.seq
                : parseInt(b.seq) || 0
              : 0
          return seqA - seqB
        })

        // 需要多次遍历，确保所有子项都能找到父项
        let hasUnprocessed = true
        while (hasUnprocessed && childItems.length > 0) {
          hasUnprocessed = false
          const remainingItems = []

          childItems.forEach((item) => {
            const rowid = item.rowid || item.id
            const parentid = item.parentid

            // 跳过已处理的项
            if (processedIds.has(rowid)) {
              return
            }

            // 查找父项在 flatData 中的位置
            const parentIndex = flatData.findIndex((row) => {
              const parentRowid = row.rowid || row.id
              return parentRowid === parentid
            })

            if (parentIndex >= 0) {
              // 找到父项，插入到父项后面
              // 找到父项后面最后一个子项的位置
              let insertIndex = parentIndex + 1
              while (
                insertIndex < flatData.length &&
                (flatData[insertIndex].rowid || flatData[insertIndex].id) !==
                  parentid &&
                flatData[insertIndex].parentid === parentid
              ) {
                insertIndex++
              }
              const rowData = this.createRowData(item, true, rowid)
              flatData.splice(insertIndex, 0, rowData)
              processedIds.add(rowid)
            } else {
              // 如果找不到父项，标记为未处理，等待下一轮
              remainingItems.push(item)
              hasUnprocessed = true
            }
          })

          // 更新待处理的子项列表
          childItems.length = 0
          childItems.push(...remainingItems)
        }

        // 处理剩余未找到父项的项（可能是数据异常）
        this.tableItems.forEach((item) => {
          const rowid = item.rowid || item.id
          if (!processedIds.has(rowid)) {
            const rowData = this.createRowData(item, false, rowid)
            flatData.push(rowData)
            processedIds.add(rowid)
          }
        })

        this.tableData = flatData

        // 构建公式索引并计算一次
        this.buildFormulaEngine()
        this.recomputeAllFormulas()
      },
      // 创建行数据
      createRowData(item, isChild, rowid) {
        const rowData = {
          ...item,
          rowid: rowid || item.rowid || item.id,
          seq:
            item.seq !== undefined
              ? item.seq
              : isChild
              ? ''
              : item.categorySeq || item.id || '',
          isCategory: item.isCategory || false,
        }

        // 初始化年份数据
        this.yearColumns.forEach((year) => {
          rowData[`year_${year}`] = item[`year_${year}`] || ''
        })

        // 初始化备注
        rowData.remark = item.remark || ''

        // 如果有传入的数据，填充值
        if (this.surveyData && this.surveyData[rowid]) {
          const savedData = this.surveyData[rowid]
          this.yearColumns.forEach((year) => {
            if (savedData[year] !== undefined) {
              rowData[`year_${year}`] = savedData[year]
            }
          })
          if (savedData.remark !== undefined) {
            rowData.remark = savedData.remark
          }
        }

        return rowData
      },
      // 加载详情数据并回显
      async loadDetailData() {
        // 如果有 uploadId 和 auditedUnitId，调用接口获取详情数据
        const uploadId =
          this.uploadId || this.surveyData.uploadId || this.surveyData.id
        const auditedUnitId =
          this.auditedUnitId || this.surveyData.auditedUnitId

        // 只要有 uploadId 就尝试获取回显数据
        if (uploadId) {
          try {
            const params = {
              uploadId: uploadId,
              auditedUnitId: auditedUnitId,
              type: this.requestType,
            }
            const res = await getSurveyDetail(params)
            console.log('固定表详情数据', res)
            if (res && res.code === 200 && res.value) {
              // 将接口返回的数据转换为表格数据格式
              const detailData = Array.isArray(res.value)
                ? res.value
                : res.value.items || res.value.records || []

              // 按 rowid 分组数据
              const dataByRowid = {}
              detailData.forEach((item) => {
                if (item.rowid) {
                  if (!dataByRowid[item.rowid]) {
                    dataByRowid[item.rowid] = {}
                  }
                  dataByRowid[item.rowid][item.rkey] = item.rvalue
                }
              })

              // 回显数据到表格
              this.tableData.forEach((row) => {
                const rowid = row.rowid || row.id
                const rowData = dataByRowid[rowid]

                if (rowData) {
                  // 回显基本信息
                  if (rowData['序号'] !== undefined) {
                    row.seq = rowData['序号']
                  }
                  if (rowData['项目'] !== undefined) {
                    row.itemName = rowData['项目']
                  }
                  if (rowData['单位'] !== undefined) {
                    row.unit = rowData['单位']
                  }
                  if (rowData['备注'] !== undefined) {
                    row.remark = rowData['备注']
                  }

                  // 回显年份数据
                  this.yearColumns.forEach((year) => {
                    if (rowData[year] !== undefined) {
                      row[`year_${year}`] = rowData[year]
                    }
                  })
                }
              })

              // 强制更新视图
              this.$forceUpdate()

              // 回显后根据公式重算
              this.recomputeAllFormulas()
            }
          } catch (err) {
            console.error('获取固定表详情失败', err)
          }
        }
      },
      // 获取假数据（用于测试）
      getMockTableData() {
        return [
          {
            id: '1',
            itemName: '班级数',
            unit: '个',
            isCategory: false,
            seq: 1,
            year_2022: '',
            year_2023: '',
            year_2024: '',
            remark: '',
          },
          {
            id: '2',
            itemName: '幼儿学生人数',
            unit: '人',
            isCategory: false,
            seq: 2,
            year_2022: '',
            year_2023: '',
            year_2024: '',
            remark: '',
          },
          {
            id: 'III',
            itemName: '在取做保职工总人数',
            unit: '人',
            isCategory: true,
            categorySeq: 'III',
            seq: 'III',
          },
          {
            id: '3-1',
            itemName: '行政管理人员数',
            unit: '人',
            isCategory: false,
            categoryId: 'III',
            categorySeq: 'III',
            seq: 3,
            year_2022: '',
            year_2023: '',
            year_2024: '',
            remark: '',
          },
          {
            id: '3-2',
            itemName: '教师人数',
            unit: '人',
            isCategory: false,
            categoryId: 'III',
            categorySeq: 'III',
            seq: 4,
            year_2022: '',
            year_2023: '',
            year_2024: '',
            remark: '',
          },
          {
            id: '3-3',
            itemName: '保育员人数',
            unit: '人',
            isCategory: false,
            categoryId: 'III',
            categorySeq: 'III',
            seq: 5,
            year_2022: '',
            year_2023: '',
            year_2024: '',
            remark: '',
          },
        ]
      },
      // 获取行样式类名
      getRowClassName({ row }) {
        if (row.isCategory) {
          return 'category-row'
        }
        return ''
      },
      // 单元格输入事件
      handleCellInput(row, year) {
        // 实时验证勾稽关系
        this.validateLinkage(row, year)
        // 实时联动计算
        this.recomputeDependentsForRow(row, year)
      },
      // 单元格失焦事件
      handleCellBlur(row, year) {
        // 验证格式和非空
        this.validateCell(row, year)
        // 验证勾稽关系
        this.validateLinkage(row, year)
        // 失焦后再次联动计算，确保取整/格式等影响后结果一致
        this.recomputeDependentsForRow(row, year)
      },
      // 验证单元格（非空和格式验证）
      validateCell(row, year) {
        const fieldName = `year_${year}`
        const value = row[fieldName]

        // 非空验证
        if (row.validateRules && row.validateRules.required && !value) {
          this.showFieldError(
            row,
            year,
            `${row.itemName}的${year}年数据不能为空`
          )
          return false
        }

        // 格式验证
        if (value && row.validateRules) {
          if (row.validateRules.type === 'number') {
            const numValue = Number(value)
            if (isNaN(numValue)) {
              this.showFieldError(
                row,
                year,
                `${row.itemName}的${year}年数据必须是数字`
              )
              return false
            }
            if (
              row.validateRules.min !== undefined &&
              numValue < row.validateRules.min
            ) {
              this.showFieldError(
                row,
                year,
                `${row.itemName}的${year}年数据不能小于${row.validateRules.min}`
              )
              return false
            }
            if (
              row.validateRules.max !== undefined &&
              numValue > row.validateRules.max
            ) {
              this.showFieldError(
                row,
                year,
                `${row.itemName}的${year}年数据不能大于${row.validateRules.max}`
              )
              return false
            }
          }
        }

        return true
      },
      // 验证勾稽关系
      validateLinkage(row, year) {
        if (!row.linkageRules) return true

        const { parent, relation } = row.linkageRules

        if (relation === 'sum') {
          // 验证子项之和等于父项
          const parentRow = this.tableData.find((r) => r.id === parent)
          if (!parentRow || parentRow.isCategory) return true

          const children = this.tableData.filter(
            (r) => r.categoryId === parent && !r.isCategory
          )

          const parentValue = Number(parentRow[`year_${year}`]) || 0
          const sumValue = children.reduce((sum, child) => {
            return sum + (Number(child[`year_${year}`]) || 0)
          }, 0)

          if (parentValue !== sumValue) {
            // 可以选择自动修正或提示错误
            // 这里仅提示，不自动修正
            console.warn(
              `${parentRow.itemName}的${year}年数据(${parentValue})与子项之和(${sumValue})不相等`
            )
          }
        }

        return true
      },
      // 显示字段错误
      showFieldError(row, year, message) {
        // 这里可以添加更详细的错误提示
        console.error(message)
      },
      // 保存前验证
      validateBeforeSave() {
        this.validationErrors = []
        let isValid = true

        // 验证所有单元格
        this.tableData.forEach((row) => {
          if (row.isCategory) return

          this.yearColumns.forEach((year) => {
            const cellValid = this.validateCell(row, year)
            if (!cellValid) {
              isValid = false
              this.validationErrors.push({
                row: row.itemName,
                year,
                message: `${row.itemName}的${year}年数据验证失败`,
              })
            }
          })

          // 验证勾稽关系
          this.yearColumns.forEach((year) => {
            const linkageValid = this.validateLinkage(row, year)
            if (!linkageValid) {
              isValid = false
            }
          })
        })

        // 验证所有勾稽关系
        this.validateAllLinkages()

        return isValid
      },
      // 验证所有勾稽关系
      validateAllLinkages() {
        const categories = this.tableData.filter((r) => r.isCategory)

        categories.forEach((category) => {
          const children = this.tableData.filter(
            (r) => r.categoryId === category.id && !r.isCategory
          )

          this.yearColumns.forEach((year) => {
            const categoryValue = Number(category[`year_${year}`]) || 0
            const sumValue = children.reduce((sum, child) => {
              return sum + (Number(child[`year_${year}`]) || 0)
            }, 0)

            if (categoryValue !== 0 && categoryValue !== sumValue) {
              this.validationErrors.push({
                row: category.itemName,
                year,
                message: `${category.itemName}的${year}年数据(${categoryValue})与子项之和(${sumValue})不相等`,
              })
            }
          })
        })
      },
      // 关闭弹窗
      handleClose() {
        this.dialogVisible = false
        this.$emit('update:visible', false)
      },
      // 取消
      handleCancel() {
        this.handleClose()
      },
      // 保存
      async handleSave() {
        // 验证数据
        if (!this.validateBeforeSave()) {
          const errorMessages = this.validationErrors
            .map((err) => `${err.row}的${err.year}年：${err.message}`)
            .join('\n')
          Message.error('数据验证失败：\n' + errorMessages)
          return
        }

        try {
          // 判断是否有数据（编辑模式）：如果有 uploadId，说明是编辑已有数据
          const hasData = !!(
            this.uploadId ||
            this.surveyData.uploadId ||
            this.surveyData.id
          )

          // 格式化保存数据为接口需要的格式
          const saveData = []

          // 遍历所有行数据
          this.tableData.forEach((row) => {
            const rowid = row.rowid || row.id

            // 跳过分类行（如果分类行不需要保存基本信息）
            if (!row.isCategory) {
              // 保存基本信息：序号、项目、单位
              if (row.seq !== undefined && row.seq !== null && row.seq !== '') {
                saveData.push({
                  rowid: rowid,
                  rkey: '序号',
                  rvalue: String(row.seq),
                })
              }

              if (row.itemName) {
                saveData.push({
                  rowid: rowid,
                  rkey: '项目',
                  rvalue: String(row.itemName),
                })
              }

              if (row.unit) {
                saveData.push({
                  rowid: rowid,
                  rkey: '单位',
                  rvalue: String(row.unit),
                })
              }
            }

            // 保存年份数据（所有行都可以有年份数据）
            this.yearColumns.forEach((year) => {
              const yearValue = row[`year_${year}`]
              if (
                yearValue !== undefined &&
                yearValue !== null &&
                yearValue !== ''
              ) {
                saveData.push({
                  rowid: rowid,
                  rkey: String(year),
                  rvalue: String(yearValue),
                })
              }
            })

            // 保存备注（所有行都可以有备注）
            if (
              row.remark !== undefined &&
              row.remark !== null &&
              row.remark !== ''
            ) {
              saveData.push({
                rowid: rowid,
                rkey: '备注',
                rvalue: String(row.remark),
              })
            }
          })

          // 为每条数据添加公共字段
          const finalSaveData = saveData.map((item) => {
            const dataItem = {
              ...item,
              auditedUnitId:
                this.auditedUnitId || this.surveyData.auditedUnitId || '',
              surveyTemplateId:
                this.surveyTemplateId || this.surveyData.surveyTemplateId || '',
              catalogId: this.catalogId || this.surveyData.catalogId || '',
              taskId: this.taskId || this.surveyData.taskId || '',
              type: this.requestType,
            }

            // 如果有数据（编辑模式），添加 uploadId 字段
            if (hasData) {
              dataItem.uploadId =
                this.uploadId ||
                this.surveyData.uploadId ||
                this.surveyData.id ||
                ''
            }

            return dataItem
          })

          console.log('保存数据:', finalSaveData)

          // 调用保存接口
          const res = await saveSingleRecordSurvey(finalSaveData)
          if (res && res.code === 200) {
            Message.success('保存成功')
            // 触发保存事件
            this.$emit('save', finalSaveData)
            // 触发刷新事件
            this.$emit('refresh')
            this.handleClose()
          } else {
            Message.error(res.message || '保存失败')
          }
        } catch (err) {
          console.error('保存失败', err)
          // Message.error(err.message || '保存失败')
        }
      },
      // 构建 cellCode 索引与依赖图
      buildFormulaEngine() {
        const index = {}
        const deps = {}
        this.tableData.forEach((row) => {
          if (row && row.cellCode) {
            index[row.cellCode] = row
          }
        })
        // 构建依赖映射：A1 -> [依赖 A1 的行...]
        this.tableData.forEach((row) => {
          if (!row || !row.calculationFormula) return
          const codes =
            row.calculationFormula.toString().match(/[A-Z]+\d+/g) || []
          codes.forEach((code) => {
            if (!deps[code]) deps[code] = new Set()
            deps[code].add(row)
          })
        })
        this.cellCodeIndex = index
        this.dependentsMap = deps
      },
      // 重新计算一个公式行在某年的值
      recomputeRowForYear(row, year) {
        if (!row || !row.calculationFormula) return
        const expr = row.calculationFormula.toString()
        // 替换变量为对应年的数值
        const replaced = expr.replace(/[A-Z]+\d+/g, (code) => {
          const refRow = this.cellCodeIndex[code]
          const v = refRow ? Number(refRow[`year_${year}`]) : 0
          return isNaN(v) ? '0' : String(v)
        })
        // 仅允许数字与运算符
        const safe = this.safeEvalExpression(replaced)
        if (safe !== null && !isNaN(safe)) {
          row[`year_${year}`] = String(safe)
        }
      },
      // 在某年针对一个输入行，联动所有依赖它的行
      recomputeDependentsForRow(row, year) {
        if (!row) return
        const code = row.cellCode
        if (!code) return
        const dependents = this.dependentsMap[code]
        if (!dependents || dependents.size === 0) return
        dependents.forEach((depRow) => this.recomputeRowForYear(depRow, year))
        // 可能存在链式依赖，递归触发
        dependents.forEach((depRow) =>
          this.recomputeDependentsForRow(depRow, year)
        )
      },
      // 对所有含公式的行、所有年重算
      recomputeAllFormulas() {
        if (!this.yearColumns || this.yearColumns.length === 0) return
        const formulaRows = this.tableData.filter(
          (r) => r && r.calculationFormula
        )
        this.yearColumns.forEach((year) => {
          formulaRows.forEach((r) => this.recomputeRowForYear(r, year))
        })
        this.$forceUpdate()
      },
      // 简单安全表达式求值：仅支持数字、+ - * / 和括号
      safeEvalExpression(expr) {
        const cleaned = expr.replace(/\s+/g, '')
        if (!/^[-+*/().\d]+$/.test(cleaned)) {
          // 存在不允许的字符，放弃计算
          return null
        }
        try {
          // eslint-disable-next-line no-new-func
          const fn = new Function(`return (${cleaned})`)
          const res = fn()
          return typeof res === 'number' && isFinite(res) ? res : null
        } catch (e) {
          return null
        }
      },
    },
  }
</script>

<style scoped lang="scss">
  .dialog-footer {
    text-align: center;
    margin-top: 20px;
    .el-button {
      margin: 0 10px;
    }
  }

  ::v-deep .el-dialog__header {
    padding: 20px 20px 10px;
    .el-dialog__title {
      font-size: 18px;
      font-weight: 600;
      color: #303133;
    }
  }

  // 分类行样式
  ::v-deep .category-row {
    background-color: #f5f7fa !important;

    td {
      background-color: #f5f7fa !important;
      font-weight: bold;
    }

    .category-name {
      color: #409eff;
      font-weight: bold;
    }

    .category-seq {
      color: #409eff;
      font-weight: bold;
    }
  }

  // 表格输入框样式
  ::v-deep .el-table {
    .el-input {
      .el-input__inner {
        border: none;
        padding: 0 5px;
        text-align: center;

        &:focus {
          border: 1px solid #409eff;
        }
      }
    }
  }
</style>
