<template>
  <div class="fixed-assets-table-container">
    <el-table
      :data="flattenedTableData"
      border
      style="width: 100%"
      size="small"
      :row-class-name="getRowClassName"
    >
      <!-- 序号列 -->
      <!-- <el-table-column prop="seq" label="序号" width="80" align="center">
        <template slot-scope="scope">
          <span v-if="scope.row.isCategory" class="category-seq">
            —
          </span>
          <span v-else>{{ scope.row.seq }}</span>
        </template>
      </el-table-column> -->

      <!-- 动态表头列 -->
      <el-table-column
        v-for="column in dynamicColumns"
        :key="column.prop"
        :prop="column.prop"
        :label="column.label"
        :min-width="column.minWidth || 120"
        :align="column.align || 'center'"
      >
        <template slot-scope="scope">
          <!-- parentid 为 -1 的行只读显示 -->
          <span
            v-if="
              scope.row.parentid === '-1' ||
              scope.row.parentid === -1 ||
              scope.row.parentId === '-1' ||
              scope.row.parentId === -1 ||
              scope.row.isCategory
            "
            class="category-value"
          >
            {{ scope.row[column.prop] || '-' }}
          </span>
          <!-- 子项可编辑 -->
          <el-date-picker
            v-else-if="column.type === 'date'"
            v-model="scope.row[column.prop]"
            type="date"
            placeholder="选择日期"
            size="mini"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
            :disabled="
              isViewMode ||
              scope.row.notDeletable === true ||
              scope.row.fromTemplate === true ||
              scope.row.notEditable === true
            "
            style="width: 100%"
          />
          <el-input
            v-else
            v-model="scope.row[column.prop]"
            :placeholder="column.placeholder || '请输入' + column.label"
            size="mini"
            :disabled="
              isViewMode ||
              scope.row.notDeletable === true ||
              scope.row.fromTemplate === true ||
              scope.row.notEditable === true
            "
            @blur="handleCellBlur(scope.row, column.prop)"
          />
        </template>
      </el-table-column>

      <!-- 操作列（仅非查看模式显示） -->
      <el-table-column
        v-if="!isViewMode"
        label="操作"
        width="100"
        align="center"
        fixed="right"
      >
        <template slot-scope="scope">
          <div
            v-if="scope.row.parentid === '-1' || scope.row.parentid === -1"
            class="operation-buttons"
          >
            <el-button
              type="text"
              size="mini"
              icon="el-icon-plus"
              :disabled="isViewMode"
              @click="handleAddRow(scope.row)"
            />
            <!-- <el-button
              type="text"
              size="mini"
              icon="el-icon-minus"
              :disabled="isViewMode"
              @click="handleDeleteRow(scope.row)"
            /> -->
          </div>
          <div v-else class="operation-buttons">
            <el-button
              type="text"
              size="mini"
              icon="el-icon-minus"
              :disabled="
                isViewMode ||
                scope.row.notDeletable === true ||
                scope.row.fromTemplate === true ||
                scope.row.notEditable === true
              "
              @click="handleDeleteChildRow(scope.row)"
            />
          </div>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

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

  export default {
    name: 'FixedAssetsTable',
    props: {
      // 表格数据配置（嵌套结构）
      tableItems: {
        type: Array,
        default: () => [],
      },
      // 是否有保存的数据
      savedData: {
        type: [Object, Array],
        default: () => ({}),
      },
      // 是否查看模式
      isViewMode: {
        type: Boolean,
        default: false,
      },
      // 固定字段标签（逗号分隔的字符串）
      fixedFields: {
        type: String,
        default: '',
      },
      // 固定字段ID（逗号分隔的字符串）
      fixedFieldids: {
        type: String,
        default: '',
      },
      // 保存所需的公共字段
      auditedUnitId: {
        type: String,
        default: '',
      },
      surveyTemplateId: {
        type: String,
        default: '',
      },
      catalogId: {
        type: String,
        default: '',
      },
      uploadId: {
        type: String,
        default: '',
      },
      // 动态表调查填报表格的行ID
      periodRecordId: {
        type: String,
        default: '',
      },
    },
    data() {
      return {
        // 嵌套的表格数据
        fixedAssetsData: [],
        // 验证错误
        validationErrors: [],
        // 记录被删除的行rowid/id，用于保存时过滤
        deletedRowids: [],
        // 扁平化的表格数据（响应式）
        flattenedData: [],
        autoIdSeed: 1,
        // 原始保存的数据（用于回显）
        rawSavedData: null,
      }
    },
    computed: {
      // 扁平化的表格数据（从嵌套结构生成）
      flattenedTableData() {
        return this.flattenedData
      },
      // 动态表头列配置
      dynamicColumns() {
        if (!this.fixedFields || !this.fixedFieldids) {
          // 如果没有 fixedFields，返回默认列配置
          return this.getDefaultColumns()
        }

        const labels = this.fixedFields.split(',').map((item) => item.trim())
        const ids = this.fixedFieldids.split(',').map((item) => item.trim())

        return labels.map((label, index) => {
          const fieldId = ids[index] || `field_${index}`
          // 数据中的字段名就是 label（中文），所以 prop 使用 label
          // fieldId 用于保存时映射回字段ID
          const prop = label
          // 根据字段名判断类型
          const isDateField =
            label.includes('日期') ||
            label.includes('时间') ||
            label.includes('Date') ||
            label.includes('Time')

          return {
            prop: prop, // 使用中文字段名作为 prop，直接对应数据中的键名
            fieldId: fieldId, // 保存字段ID，用于保存时映射
            label: label,
            minWidth: isDateField ? 180 : 120,
            align: 'center',
            type: isDateField ? 'date' : 'input',
            placeholder: `请输入${label}`,
          }
        })
      },
    },
    watch: {
      tableItems: {
        handler(newVal) {
          if (newVal && newVal.length > 0) {
            // 若 tableItems 为扁平结构（带 parentId/parentid），按父子关系组装后再渲染
            const normalized = this.normalizeTableItemsSource(newVal)
            this.fixedAssetsData =
              normalized && normalized.length > 0
                ? normalized
                : this.deepClone(newVal)
          } else {
            // 不使用假数据，等待接口返回数据
            this.fixedAssetsData = []
          }
          // 在渲染前将传入的子项标记为只读
          this.markInitialChildrenReadonly()
          // 重新生成扁平数据
          this.generateFlattenedData()
        },
        immediate: true,
        deep: true,
      },
      savedData: {
        handler(newVal) {
          console.log('newVal', newVal)
          // 保存原始数据用于回显
          this.rawSavedData = newVal
          // 回显新数据时清空已删除记录
          this.deletedRowids = []
          if (newVal) {
            const normalized = this.normalizeSavedData(newVal)
            if (normalized && normalized.length > 0) {
              // 使用接口返回的数据，不使用假数据
              this.fixedAssetsData = normalized
            } else {
              // 如果没有数据，清空
              this.fixedAssetsData = []
            }
          } else {
            this.fixedAssetsData = []
          }
          // 在渲染前将传入的子项标记为只读
          this.markInitialChildrenReadonly()
          // 数据变化时重新生成扁平数据
          this.generateFlattenedData()
        },
        deep: true,
        immediate: true,
      },
    },
    methods: {
      // 将传入的子项标记为只读（不可编辑/删除），新增的行不受影响
      markInitialChildrenReadonly() {
        const data = this.fixedAssetsData || []
        data.forEach((node) => {
          if (!node || typeof node !== 'object') return
          const children = Array.isArray(node.children) ? node.children : []
          children.forEach((child) => {
            if (!child || typeof child !== 'object') return
            // 仅标记已有的传入子项（保留模板标记）
            if (child.notEditable !== false) {
              child.notEditable = true
            }
          })
        })
      },
      // 生成扁平数据
      generateFlattenedData() {
        // 先同步扁平数据中的修改到嵌套结构，避免数据丢失
        // 只有在已有扁平数据时才同步（避免初始化时出错）
        const shouldSync =
          this.flattenedData &&
          this.flattenedData.length > 0 &&
          this.fixedAssetsData &&
          this.fixedAssetsData.length > 0
        if (shouldSync) {
          this.syncFlattenedDataToNested()
        }

        const result = []
        let seq = 1

        const processItem = (item, parentCategory = null) => {
          const isCategory = this.isCategoryItem(item)
          const currentItem = this.normalizeItemNode(item)
          if (isCategory) {
            // 分类行（父项）
            const categoryRowData = {
              ...currentItem,
              seq: currentItem.categorySeq || currentItem.id,
              isCategory: true,
              categorySeq: currentItem.categorySeq || currentItem.id,
            }

            // 直接使用 currentItem 中的数据（normalizeSavedData 已经保留了所有原始字段）
            // 将所有字段值复制到 categoryRowData（除了系统字段）
            Object.keys(currentItem).forEach((key) => {
              if (
                currentItem[key] !== undefined &&
                key !== 'id' &&
                key !== 'children' &&
                key !== 'isCategory' &&
                key !== 'categorySeq' &&
                key !== 'seq' &&
                !key.startsWith('_')
              ) {
                categoryRowData[key] = currentItem[key]
              }
            })

            // 根据表头字段确保所有列都有值（如果数据中没有对应字段，初始化为空）
            this.dynamicColumns.forEach((column) => {
              if (categoryRowData[column.prop] === undefined) {
                categoryRowData[column.prop] = currentItem[column.prop] || ''
              }
            })

            result.push(categoryRowData)

            // 处理分类下的子项
            if (currentItem.children && Array.isArray(currentItem.children)) {
              currentItem.children.forEach((child) => {
                processItem(child, currentItem)
              })
            }
          } else {
            // 普通行
            const rowData = {
              ...currentItem,
              seq: seq++,
              isCategory: false,
            }

            // 如果有父分类，设置分类信息
            if (parentCategory) {
              rowData.categoryId = parentCategory.id
              rowData.categorySeq =
                parentCategory.categorySeq || parentCategory.id
            }

            // 直接使用 currentItem 中的数据（normalizeSavedData 已经保留了所有原始字段）
            // 将所有字段值复制到 rowData（除了系统字段）
            Object.keys(currentItem).forEach((key) => {
              if (
                currentItem[key] !== undefined &&
                key !== 'id' &&
                key !== 'children' &&
                key !== 'isCategory' &&
                key !== 'categorySeq' &&
                key !== 'seq' &&
                !key.startsWith('_')
              ) {
                rowData[key] = currentItem[key]
              }
            })

            // 根据表头字段确保所有列都有值（优先使用数据中的值，如果没有则初始化为空）
            this.dynamicColumns.forEach((column) => {
              // 如果数据中没有该字段，初始化为空字符串
              if (rowData[column.prop] === undefined) {
                rowData[column.prop] = currentItem[column.prop] || ''
              }
            })

            result.push(rowData)

            // 如果有子项，递归处理
            if (item.children && Array.isArray(item.children)) {
              item.children.forEach((child) => {
                processItem(child, item)
              })
            }
          }
        }

        // 处理所有项
        this.fixedAssetsData.forEach((item) => {
          processItem(item)
        })

        // 使用 Vue.set 确保响应式
        this.$set(this, 'flattenedData', result)
      },
      // 深拷贝
      deepClone(obj) {
        if (obj === null || typeof obj !== 'object') return obj
        if (obj instanceof Date) return new Date(obj.getTime())
        if (obj instanceof Array) return obj.map((item) => this.deepClone(item))
        if (typeof obj === 'object') {
          const clonedObj = {}
          for (const key in obj) {
            if (obj.hasOwnProperty(key)) {
              clonedObj[key] = this.deepClone(obj[key])
            }
          }
          return clonedObj
        }
      },
      // 将三元组明细数组（rowid,parentId,rkey,rvalue）聚合为树形行数据
      transformTripletArrayToRows(items) {
        if (!Array.isArray(items) || items.length === 0) return []
        const rowsByRowid = new Map()
        const parentRowids = new Set()
        items.forEach((rec) => {
          if (!rec || typeof rec !== 'object') return
          const rowid = rec.rowid || rec.rowId
          if (!rowid) return
          const parentId = rec.parentId ?? rec.parentID ?? rec.parentid
          if (parentId && parentId !== '-1' && parentId !== -1) {
            parentRowids.add(String(parentId))
          }
          if (!rowsByRowid.has(rowid)) {
            rowsByRowid.set(rowid, {
              id: rowid,
              rowid: rowid,
              parentid:
                parentId === undefined || parentId === null
                  ? ''
                  : String(parentId),
              children: [],
            })
          }
          const row = rowsByRowid.get(rowid)
          const key = rec.rkey
          const val = rec.rvalue
          if (key !== undefined) {
            row[key] = val
          }
        })
        const allRows = Array.from(rowsByRowid.values())
        allRows.forEach((row) => {
          if (
            row.parentid === '-1' ||
            row.parentid === -1 ||
            parentRowids.has(row.rowid)
          ) {
            row.isCategory = true
          }
        })
        const byRowid = new Map(allRows.map((r) => [r.rowid, r]))
        const roots = []
        allRows.forEach((row) => {
          const p = row.parentid
          if (p && p !== '-1' && p !== -1) {
            const parent = byRowid.get(String(p))
            if (parent) {
              if (!Array.isArray(parent.children)) parent.children = []
              parent.children.push(row)
              parent.isCategory = true
            } else {
              roots.push(row)
            }
          } else {
            roots.push(row)
          }
        })
        return roots
      },
      // 当没有详情数据时，tableItems 可能为扁平结构，这里根据 parentId/parentid 组装树
      normalizeTableItemsSource(items) {
        if (!Array.isArray(items) || items.length === 0) return []
        const cloned = this.deepClone(items)
        // 三元组格式直接转换
        const isTriplet =
          cloned.length > 0 &&
          cloned.every(
            (it) =>
              it &&
              typeof it === 'object' &&
              'rkey' in it &&
              'rvalue' in it &&
              ('rowid' in it || 'rowId' in it)
          )
        if (isTriplet) {
          return this.transformTripletArrayToRows(cloned)
        }
        const hasNestedChildren = cloned.some(
          (it) => it && Array.isArray(it.children) && it.children.length > 0
        )
        if (hasNestedChildren) {
          return cloned.map((it) => this.normalizeItemNode(it))
        }
        // 扁平结构：根据 parentId/parentid 组装
        const idMap = new Map()
        const rowidMap = new Map()
        const nodes = cloned.map((raw) => this.normalizeItemNode(raw))
        nodes.forEach((node, idx) => {
          const raw = cloned[idx]
          const id = node.id
          const rowid = raw.rowid || raw.rowId || node.rowid || node.id
          if (id) idMap.set(id, node)
          if (rowid) rowidMap.set(rowid, node)
        })
        const roots = []
        cloned.forEach((raw, idx) => {
          const node = nodes[idx]
          const parentKey =
            raw.parentId ??
            raw.parentid ??
            raw.parentID ??
            raw.parentCode ??
            raw.parent_code
          if (parentKey && parentKey !== '-1' && parentKey !== -1) {
            // 先按 id 匹配，再按 rowid 兜底
            const parent = idMap.get(parentKey) || rowidMap.get(parentKey)
            if (parent) {
              if (!Array.isArray(parent.children)) parent.children = []
              parent.children.push(node)
              parent.isCategory = true
            } else {
              roots.push(node)
            }
          } else {
            roots.push(node)
          }
        })
        return roots.length > 0 ? roots : nodes
      },
      // 获取行样式类名
      getRowClassName({ row }) {
        // parentid 为 -1 的行（父项）使用分类行样式
        if (
          row.parentid === '-1' ||
          row.parentid === -1 ||
          row.parentId === '-1' ||
          row.parentId === -1 ||
          row.isCategory
        ) {
          return 'category-row'
        }
        return ''
      },
      // 添加行（添加子项）
      handleAddRow(row) {
        // 先同步扁平数据中的修改到嵌套结构，避免数据丢失
        this.syncFlattenedDataToNested()

        // row 是 parentid 为 -1 的父项
        // 找到对应的父项节点
        const parentNode = this.findNodeByRowid(row.rowid)
        if (parentNode) {
          // 生成新的子项
          const newRowid = `${Date.now()}.${Math.random()
            .toString(36)
            .substr(2, 9)}`
          const newItem = {
            parentid: row.rowid, // 设置父项的 rowid
            rowid: newRowid,
            id: newRowid, // 临时使用 rowid 作为 id
          }

          // 根据表头字段初始化新项的所有字段
          this.dynamicColumns.forEach((column) => {
            newItem[column.prop] = ''
          })

          // 在父项的 children 数组末尾添加新行
          if (!parentNode.children) {
            this.$set(parentNode, 'children', [])
          }
          parentNode.children.push(newItem)

          // 重新生成扁平数据（generateFlattenedData 内部会再次同步，确保数据不丢失）
          this.generateFlattenedData()
          Message.success('添加子项成功')
        } else {
          Message.error('找不到父项')
        }
      },
      // 删除行（删除父项下的最后一个子项）
      handleDeleteRow(row) {
        // 先同步扁平数据中的修改到嵌套结构，避免数据丢失
        this.syncFlattenedDataToNested()

        // row 是 parentid 为 -1 的父项
        // 找到对应的父项节点
        const parentNode = this.findNodeByRowid(row.rowid)
        if (
          parentNode &&
          parentNode.children &&
          parentNode.children.length > 0
        ) {
          // 删除最后一个子项
          const removedChild = parentNode.children.pop()
          // 记录被删除的行标识，保存时过滤
          const removedKey = String(
            (removedChild &&
              (removedChild.rowid || removedChild.rowId || removedChild.id)) ||
              ''
          )
          if (removedKey) {
            if (!this.deletedRowids.includes(removedKey)) {
              this.deletedRowids.push(removedKey)
            }
            // 同步从扁平数据中移除该行，避免同步时被回填
            const withoutRemoved = (this.flattenedData || []).filter((r) => {
              const rk = String(r.rowid || r.rowId || r.id || '')
              return rk !== removedKey
            })
            this.$set(this, 'flattenedData', withoutRemoved)
          }
          // 重新生成扁平数据
          this.generateFlattenedData()
          Message.success('删除子项成功')
        } else {
          Message.warning('该父项下没有可删除的子项')
        }
      },
      // 删除子项（点击子项行的减号删除当前这条）
      handleDeleteChildRow(row) {
        // 模板数据不可删除
        if (row && (row.notDeletable === true || row.fromTemplate === true)) {
          Message.warning('该行由模板生成，无法删除')
          return
        }
        // 先同步扁平数据中的修改到嵌套结构，避免数据丢失
        this.syncFlattenedDataToNested()
        const childRowid = row.rowid || row.rowId || row.id
        if (!childRowid) {
          Message.error('无法识别该行标识，删除失败')
          return
        }
        // 记录被删除的行标识，保存时过滤
        const key = String(childRowid)
        if (key && !this.deletedRowids.includes(key)) {
          this.deletedRowids.push(key)
        }
        // 从整棵树中移除此节点
        const removed = this.removeRowByRowid(childRowid)
        if (removed) {
          // 同步从扁平数据中移除该行，避免同步时被回填
          const withoutRemoved = (this.flattenedData || []).filter((r) => {
            const rk = String(r.rowid || r.rowId || r.id || '')
            return rk !== key
          })
          this.$set(this, 'flattenedData', withoutRemoved)
          // 重新生成扁平数据并刷新视图
          this.generateFlattenedData()
          this.$nextTick(() => {
            this.$forceUpdate()
          })
          Message.success('删除成功')
        } else {
          Message.warning('未找到可删除的记录')
        }
      },
      // 在嵌套数据中移除指定 rowid 的节点
      removeRowByRowid(targetRowid) {
        if (!Array.isArray(this.fixedAssetsData)) return false
        const toKey = (n) => String(n.rowid || n.rowId || n.id || '')
        const targetKey = String(targetRowid)
        // 尝试在根级删除
        const idx = this.fixedAssetsData.findIndex(
          (n) => toKey(n) === targetKey
        )
        if (idx >= 0) {
          this.fixedAssetsData.splice(idx, 1)
          return true
        }
        // 递归在 children 中删除
        const dfsRemove = (nodes) => {
          for (const node of nodes) {
            if (Array.isArray(node.children) && node.children.length > 0) {
              const i = node.children.findIndex((c) => toKey(c) === targetKey)
              if (i >= 0) {
                node.children.splice(i, 1)
                return true
              }
              if (dfsRemove(node.children)) return true
            }
          }
          return false
        }
        return dfsRemove(this.fixedAssetsData)
      },
      // 同步扁平数据中的修改到嵌套结构
      syncFlattenedDataToNested() {
        const flatData = this.flattenedData
        if (!flatData || flatData.length === 0) return

        // 建立 rowid 到嵌套节点的映射
        const nodeMap = new Map()
        const buildMap = (items) => {
          items.forEach((item) => {
            const rowid = item.rowid || item.rowId || item.id
            if (rowid) {
              nodeMap.set(rowid, item)
            }
            if (item.children && Array.isArray(item.children)) {
              buildMap(item.children)
            }
          })
        }
        buildMap(this.fixedAssetsData)

        // 将扁平数据中的修改同步到嵌套结构
        flatData.forEach((flatRow) => {
          const rowid = flatRow.rowid || flatRow.rowId || flatRow.id
          if (!rowid) return

          const nestedNode = nodeMap.get(rowid)
          if (nestedNode) {
            // 同步所有表头字段的值（使用 hasOwnProperty 确保即使值为空字符串也能同步）
            this.dynamicColumns.forEach((column) => {
              if (flatRow.hasOwnProperty(column.prop)) {
                nestedNode[column.prop] = flatRow[column.prop]
              }
            })
            // 同步其他字段（除了系统字段）
            Object.keys(flatRow).forEach((key) => {
              if (
                key !== 'id' &&
                key !== 'rowid' &&
                key !== 'rowId' &&
                key !== 'children' &&
                key !== 'isCategory' &&
                key !== 'categorySeq' &&
                key !== 'seq' &&
                key !== 'categoryId' &&
                !key.startsWith('_')
              ) {
                // 使用 hasOwnProperty 确保即使值为空字符串也能同步
                if (flatRow.hasOwnProperty(key)) {
                  nestedNode[key] = flatRow[key]
                }
              }
            })
            // 确保 parentid 被保留
            if (flatRow.hasOwnProperty('parentid')) {
              nestedNode.parentid = flatRow.parentid
            }
          } else {
            // 如果找不到节点，可能是新添加的行，需要添加到对应的父节点下
            const parentid = flatRow.parentid || flatRow.parentId
            if (parentid && parentid !== '-1') {
              const parentNode = nodeMap.get(parentid)
              if (parentNode) {
                // 创建新节点并添加到父节点的 children 中
                const newNode = {
                  ...flatRow,
                  id: rowid,
                  rowid: rowid,
                  parentid: parentid,
                }
                // 移除系统字段
                delete newNode.isCategory
                delete newNode.categorySeq
                delete newNode.seq
                delete newNode.categoryId

                if (!parentNode.children) {
                  this.$set(parentNode, 'children', [])
                }
                // 检查是否已存在，避免重复添加
                const exists = parentNode.children.some(
                  (child) => (child.rowid || child.rowId || child.id) === rowid
                )
                if (!exists) {
                  parentNode.children.push(newNode)
                } else {
                  // 如果已存在，更新数据
                  const existingNode = parentNode.children.find(
                    (child) =>
                      (child.rowid || child.rowId || child.id) === rowid
                  )
                  if (existingNode) {
                    // 同步所有字段
                    this.dynamicColumns.forEach((column) => {
                      if (flatRow.hasOwnProperty(column.prop)) {
                        existingNode[column.prop] = flatRow[column.prop]
                      }
                    })
                    Object.keys(flatRow).forEach((key) => {
                      if (
                        key !== 'id' &&
                        key !== 'rowid' &&
                        key !== 'rowId' &&
                        key !== 'children' &&
                        key !== 'isCategory' &&
                        key !== 'categorySeq' &&
                        key !== 'seq' &&
                        key !== 'categoryId' &&
                        !key.startsWith('_')
                      ) {
                        if (flatRow.hasOwnProperty(key)) {
                          existingNode[key] = flatRow[key]
                        }
                      }
                    })
                  }
                }
              }
            }
          }
        })
      },
      // 根据 rowid 查找节点
      findNodeByRowid(rowid) {
        const findInArray = (items) => {
          for (const item of items) {
            if (item.rowid === rowid || item.rowId === rowid) {
              return item
            }
            if (item.children && Array.isArray(item.children)) {
              const found = findInArray(item.children)
              if (found) return found
            }
          }
          return null
        }
        return findInArray(this.fixedAssetsData)
      },
      // 根据ID在保存的数据中查找（支持通过 id 或 rowid 查找）
      findSavedItemById(id) {
        // 优先从 rawSavedData 中查找（原始数据）
        const dataSource = this.rawSavedData || this.savedData
        if (!dataSource) return null

        // 递归查找（支持通过 id、rowid、rowId 匹配）
        const findInArray = (items) => {
          if (!Array.isArray(items)) return null
          for (const item of items) {
            // 匹配 id、rowid、rowId
            if (
              item.id === id ||
              item.rowid === id ||
              item.rowId === id ||
              item.itemId === id ||
              item.code === id ||
              item.key === id
            ) {
              return item
            }
            if (item.children && Array.isArray(item.children)) {
              const found = findInArray(item.children)
              if (found) return found
            }
          }
          return null
        }

        // 如果 dataSource 是数组
        if (Array.isArray(dataSource)) {
          return findInArray(dataSource)
        }

        // 如果 dataSource 是对象，尝试查找
        if (typeof dataSource === 'object') {
          // 优先查找 itemlist
          if (Array.isArray(dataSource.itemlist)) {
            const found = findInArray(dataSource.itemlist)
            if (found) return found
          }
          if (Array.isArray(dataSource.items)) {
            const found = findInArray(dataSource.items)
            if (found) return found
          }
          if (Array.isArray(dataSource.data)) {
            const found = findInArray(dataSource.data)
            if (found) return found
          }
          if (Array.isArray(dataSource.value)) {
            const found = findInArray(dataSource.value)
            if (found) return found
          }

          // 可能是一个映射对象，key 是 id
          if (dataSource[id]) {
            return dataSource[id]
          }
          // 或者是嵌套结构
          return findInArray([dataSource])
        }

        return null
      },
      // 根据ID查找分类
      findCategoryById(id) {
        const findInArray = (items) => {
          for (const item of items) {
            if (item.id === id) {
              return item
            }
            if (item.children && Array.isArray(item.children)) {
              const found = findInArray(item.children)
              if (found) return found
            }
          }
          return null
        }
        return findInArray(this.fixedAssetsData)
      },
      // 单元格失焦验证
      handleCellBlur(row, field) {
        // 实时验证格式
        if (field === 'originalValue' || field === 'depreciationExpense') {
          const value = row[field]
          if (value && !/^\d+(\.\d+)?$/.test(value)) {
            Message.warning(
              `${this.getFieldLabel(field)}格式不正确，请输入数字`
            )
          }
        }
        if (field === 'depreciationPeriod') {
          const value = row[field]
          if (value && !/^\d+$/.test(value)) {
            Message.warning(`${this.getFieldLabel(field)}必须是正整数`)
          }
        }
      },
      // 获取字段标签
      getFieldLabel(field) {
        const labels = {
          originalValue: '固定资产原值',
          depreciationPeriod: '折旧年限',
          depreciationExpense: '折旧费',
        }
        return labels[field] || field
      },
      // 获取默认列配置（当没有 fixedFields 时使用）
      getDefaultColumns() {
        return [
          {
            prop: 'unit',
            label: '计量单位',
            minWidth: 120,
            align: 'center',
            type: 'input',
            placeholder: '请输入计量单位',
          },
          {
            prop: 'originalValue',
            label: '固定资产原值',
            minWidth: 150,
            align: 'center',
            type: 'input',
            placeholder: '请输入原值',
          },
          {
            prop: 'entryDate',
            label: '入帐或竣工验收日期',
            minWidth: 180,
            align: 'center',
            type: 'date',
            placeholder: '选择日期',
          },
          {
            prop: 'depreciationPeriod',
            label: '折旧年限',
            minWidth: 120,
            align: 'center',
            type: 'input',
            placeholder: '请输入年限',
          },
          {
            prop: 'depreciationExpense',
            label: '折旧费',
            minWidth: 120,
            align: 'center',
            type: 'input',
            placeholder: '请输入费用',
          },
          {
            prop: 'fundSource',
            label: '资金来源',
            minWidth: 120,
            align: 'center',
            type: 'input',
            placeholder: '请输入来源',
          },
          {
            prop: 'remark',
            label: '备注',
            minWidth: 150,
            align: 'left',
            type: 'input',
            placeholder: '请输入备注',
          },
        ]
      },
      // 验证表单
      // validate() {
      //   this.validationErrors = []
      //   const errors = []

      //   // 验证扁平数据（因为用户编辑的是扁平数据）
      //   const flatData = this.flattenedTableData
      //   flatData.forEach((item, index) => {
      //     if (!item.isCategory) {
      //       // 非空验证
      //       if (!item.itemName || String(item.itemName).trim() === '') {
      //         errors.push(`第${item.seq}行：项目名称不能为空`)
      //       }
      //       if (!item.unit || String(item.unit).trim() === '') {
      //         errors.push(`第${item.seq}行：计量单位不能为空`)
      //       }
      //       if (
      //         !item.originalValue ||
      //         String(item.originalValue).trim() === ''
      //       ) {
      //         errors.push(`第${item.seq}行：固定资产原值不能为空`)
      //       }
      //       if (!item.entryDate || String(item.entryDate).trim() === '') {
      //         errors.push(`第${item.seq}行：入帐或竣工验收日期不能为空`)
      //       }
      //       if (
      //         !item.depreciationPeriod ||
      //         String(item.depreciationPeriod).trim() === ''
      //       ) {
      //         errors.push(`第${item.seq}行：折旧年限不能为空`)
      //       }
      //       if (
      //         !item.depreciationExpense ||
      //         String(item.depreciationExpense).trim() === ''
      //       ) {
      //         errors.push(`第${item.seq}行：折旧费不能为空`)
      //       }
      //       if (!item.fundSource || String(item.fundSource).trim() === '') {
      //         errors.push(`第${item.seq}行：资金来源不能为空`)
      //       }

      //       // 格式验证
      //       if (
      //         item.originalValue &&
      //         String(item.originalValue).trim() !== '' &&
      //         !/^\d+(\.\d+)?$/.test(String(item.originalValue))
      //       ) {
      //         errors.push(`第${item.seq}行：固定资产原值格式不正确，请输入数字`)
      //       }
      //       if (
      //         item.depreciationPeriod &&
      //         String(item.depreciationPeriod).trim() !== '' &&
      //         !/^\d+$/.test(String(item.depreciationPeriod))
      //       ) {
      //         errors.push(`第${item.seq}行：折旧年限必须是正整数`)
      //       }
      //       if (
      //         item.depreciationExpense &&
      //         String(item.depreciationExpense).trim() !== '' &&
      //         !/^\d+(\.\d+)?$/.test(String(item.depreciationExpense))
      //       ) {
      //         errors.push(`第${item.seq}行：折旧费格式不正确，请输入数字`)
      //       }
      //     }
      //   })

      //   this.validationErrors = errors
      //   return errors.length === 0
      // },
      // 获取表格数据（用于保存）
      // 需要将扁平数据同步回嵌套结构
      getTableData() {
        // 同步扁平数据的修改到嵌套结构
        const flatData = this.flattenedData
        const syncDataToNested = (items) => {
          return items.map((item) => {
            if (item.isCategory) {
              // 分类行
              const newItem = { ...item }
              if (item.children && Array.isArray(item.children)) {
                newItem.children = syncDataToNested(item.children)
              }
              return newItem
            } else {
              // 普通行，从扁平数据中同步
              const flatItem = flatData.find(
                (f) => f.id === item.id && !f.isCategory
              )
              if (flatItem) {
                return {
                  ...item,
                  itemName: flatItem.itemName,
                  unit: flatItem.unit,
                  originalValue: flatItem.originalValue,
                  entryDate: flatItem.entryDate,
                  depreciationPeriod: flatItem.depreciationPeriod,
                  depreciationExpense: flatItem.depreciationExpense,
                  fundSource: flatItem.fundSource,
                  remark: flatItem.remark,
                }
              }
              return item
            }
          })
        }

        return syncDataToNested(this.fixedAssetsData)
      },
      // 保存数据（调用 saveSingleRecordSurvey 接口）
      async saveData() {
        // 保存前校验
        const validationErrors = this.validateBeforeSave()
        if (validationErrors && validationErrors.length > 0) {
          Message.error('表单验证失败，请检查后再保存')
          return false
        }
        try {
          // 格式化保存数据为接口需要的格式
          const saveData = []
          // 需要过滤掉已删除的行
          const isDeleted = (row) => {
            const key = String(row.rowid || row.rowId || row.id || '')
            return key && this.deletedRowids.includes(key)
          }
          const flatData = (this.flattenedData || []).filter(
            (row) => !isDeleted(row)
          )

          // 建立 rowid -> id 的映射，用于计算 parentId（子项需要父项的 id）
          const rowidToIdMap = new Map()
          flatData.forEach((row) => {
            const rowid = row.rowid || row.id
            const id = row.id || row.rowid || row.rowId
            if (rowid && id) {
              rowidToIdMap.set(rowid, id)
            }
          })

          // 遍历所有行数据（包括父项和子项）
          flatData.forEach((row) => {
            const rowid = row.rowid || row.id

            // 计算 parentId：父项为 '-1'；子项为父项的 id（通过 parent 的 rowid 映射得到）
            let parentId = '-1'
            const parentRowid = row.parentid || row.parentId || row.parentID
            if (parentRowid && parentRowid !== '-1' && parentRowid !== -1) {
              parentId =
                rowidToIdMap.get(parentRowid) ||
                row.categoryId || // 兼容 generateFlattenedData 填充的父分类 id
                ''
            }

            // 遍历所有表头字段，保存每个字段的值
            this.dynamicColumns.forEach((column) => {
              const value = row[column.prop]
              // 如果值存在，添加到保存数据中（父项和子项都保存）
              if (value !== undefined && value !== null && value !== '') {
                saveData.push({
                  rowid: rowid,
                  parentId: String(parentId),
                  rkey: column.label, // 字段标签（对应 fixedFields）
                  rvalue: String(value), // 字段值
                })
              }
            })
          })

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

            // 如果有 uploadId（编辑模式），添加 uploadId 字段
            if (this.uploadId) {
              dataItem.uploadId = this.uploadId
            }

            // 添加 periodRecordId（动态表调查填报表格的行ID）
            if (this.periodRecordId) {
              dataItem.periodRecordId = this.periodRecordId
            }

            return dataItem
          })

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

          // 调用保存接口
          const res = await saveSingleRecordSurvey(finalSaveData)
          if (res && res.code === 200) {
            Message.success('保存成功')
            // 触发保存事件
            this.$emit('save', finalSaveData)
            // 触发刷新事件
            this.$emit('refresh')
            return true
          } else {
            Message.error(res?.message || '保存失败')
            return false
          }
        } catch (err) {
          console.error('保存失败', err)
          Message.error(err?.message || '保存失败')
          return false
        }
      },
      // 保存前验证
      validateBeforeSave() {
        const errors = []
        const categories = Array.isArray(this.fixedAssetsData)
          ? this.fixedAssetsData
          : []

        categories.forEach((category) => {
          const items = Array.isArray(category.items) ? category.items : []
          items.forEach((item, index) => {
            const rowNum = index + 1
            // 必填校验
            if (!item.name) {
              errors.push(
                `${category.category} 第${rowNum}行：项目名称不能为空`
              )
            }
            if (!item.unit) {
              errors.push(
                `${category.category} 第${rowNum}行：计量单位不能为空`
              )
            }
            if (
              item.originalValue === '' ||
              item.originalValue === undefined ||
              item.originalValue === null
            ) {
              errors.push(
                `${category.category} 第${rowNum}行：固定资产原值不能为空`
              )
            } else if (isNaN(Number(item.originalValue))) {
              errors.push(
                `${category.category} 第${rowNum}行：固定资产原值必须为数字`
              )
            }
            if (!item.entryDate) {
              errors.push(
                `${category.category} 第${rowNum}行：入帐或竣工验收日期不能为空`
              )
            }
            if (
              item.depreciationPeriod === '' ||
              item.depreciationPeriod === undefined ||
              item.depreciationPeriod === null
            ) {
              errors.push(
                `${category.category} 第${rowNum}行：折旧年限不能为空`
              )
            } else if (isNaN(Number(item.depreciationPeriod))) {
              errors.push(
                `${category.category} 第${rowNum}行：折旧年限必须为数字`
              )
            }
            if (
              item.depreciationExpense === '' ||
              item.depreciationExpense === undefined ||
              item.depreciationExpense === null
            ) {
              errors.push(`${category.category} 第${rowNum}行：折旧费不能为空`)
            } else if (isNaN(Number(item.depreciationExpense))) {
              errors.push(
                `${category.category} 第${rowNum}行：折旧费必须为数字`
              )
            }
            if (!item.fundSource) {
              errors.push(
                `${category.category} 第${rowNum}行：资金来源不能为空`
              )
            }
          })
        })

        this.validationErrors = errors
        return errors
      },
      isCategoryItem(item) {
        if (!item) return false
        const flag = item.isCategory
        if (typeof flag === 'boolean') return flag
        if (typeof flag === 'number') return flag !== 0
        if (typeof flag === 'string') {
          const normalized = flag.toLowerCase()
          if (['1', 'true', 'yes', 'y'].includes(normalized)) return true
        }
        if (Array.isArray(item.children) && item.children.length > 0) {
          return true
        }
        return false
      },
      // 规范化节点数据（保留所有原始字段）
      normalizeItemNode(item) {
        if (!item || typeof item !== 'object') return item
        // 深拷贝保留所有原始字段
        const cloned = this.deepClone(item)

        // 确保 id 存在
        cloned.id =
          cloned.rowid ||
          cloned.rowId ||
          cloned.id ||
          cloned.itemId ||
          cloned.code ||
          cloned.key ||
          `auto-${this.autoIdSeed++}`

        // 保留 rowid 字段（用于父子关系匹配）
        if (!cloned.rowid && !cloned.rowId) {
          cloned.rowid = cloned.id
        } else {
          cloned.rowid = cloned.rowid || cloned.rowId || cloned.id
        }

        // 规范化常用字段（如果不存在则设置默认值，但不覆盖已有值）
        if (!cloned.itemName) {
          cloned.itemName = cloned.name || cloned.title || cloned['项目'] || ''
        }
        if (cloned.unit === undefined) {
          cloned.unit = cloned.unitName || cloned['单位'] || ''
        }
        if (cloned.originalValue === undefined) {
          cloned.originalValue = cloned['原值'] || cloned.value || ''
        }
        if (cloned.entryDate === undefined) {
          cloned.entryDate =
            cloned['入帐或竣工验收日期'] || cloned.entry_date || ''
        }
        if (cloned.depreciationPeriod === undefined) {
          cloned.depreciationPeriod = cloned['折旧年限'] || cloned.period || ''
        }
        if (cloned.depreciationExpense === undefined) {
          cloned.depreciationExpense = cloned['折旧费'] || cloned.expense || ''
        }
        if (cloned.fundSource === undefined) {
          cloned.fundSource = cloned.fund_source || cloned['资金来源'] || ''
        }
        if (cloned.remark === undefined) {
          cloned.remark = cloned.note || cloned['备注'] || ''
        }
        if (!cloned.categorySeq) {
          cloned.categorySeq =
            cloned.category_code ||
            cloned.seq ||
            cloned.index ||
            cloned['序号'] ||
            cloned.id
        }

        // 如果已经是分类项，保持 isCategory 状态
        if (cloned.isCategory === undefined) {
          cloned.isCategory = false // 默认不是分类，后续会根据是否有子项来设置
        }

        // 处理 children
        if (Array.isArray(cloned.children)) {
          cloned.children = this.deepClone(cloned.children)
        } else {
          cloned.children = []
        }

        return cloned
      },
      // 规范化保存的数据
      normalizeSavedData(saved) {
        if (!saved) return null

        const extractArray = (value) => {
          if (!value) return null
          if (Array.isArray(value)) return this.deepClone(value)
          if (value && typeof value === 'object') {
            if (Array.isArray(value.itemlist))
              return this.deepClone(value.itemlist)
            if (Array.isArray(value.items)) return this.deepClone(value.items)
            if (Array.isArray(value.children))
              return this.deepClone(value.children)
            if (Array.isArray(value.data)) return this.deepClone(value.data)
            if (Array.isArray(value.value)) return this.deepClone(value.value)
            if (Array.isArray(value.records))
              return this.deepClone(value.records)
            if (Array.isArray(value.rows)) return this.deepClone(value.rows)
          }
          return null
        }

        let normalized = extractArray(saved)
        // 检测三元组格式并转换
        if (
          Array.isArray(normalized) &&
          normalized.length > 0 &&
          normalized.every(
            (it) =>
              it &&
              typeof it === 'object' &&
              'rkey' in it &&
              'rvalue' in it &&
              ('rowid' in it || 'rowId' in it)
          )
        ) {
          normalized = this.transformTripletArrayToRows(normalized)
        }
        if (!normalized && saved && typeof saved === 'object') {
          const values = Object.values(saved)
          if (
            values.length > 0 &&
            values.every(
              (item) =>
                item &&
                typeof item === 'object' &&
                (item.itemName || item.children || item.isCategory)
            )
          ) {
            normalized = this.deepClone(values)
          }
        }

        if (!normalized || normalized.length === 0) return null

        const hasNestedChildren = normalized.some(
          (item) =>
            item && Array.isArray(item.children) && item.children.length > 0
        )

        if (hasNestedChildren) {
          return normalized.map((item) => this.normalizeItemNode(item))
        }

        // 如果是扁平结构，尝试根据 parentId 组装
        // 首先建立 rowid 到节点的映射（用于根据 parentid 查找父节点）
        const itemsMapById = new Map() // 通过 id 查找节点
        const itemsMapByRowid = new Map() // 通过 rowid 查找节点（用于父子关系）

        normalized.forEach((raw) => {
          const node = this.normalizeItemNode(raw)
          // 获取节点的 id
          const nodeId = node.id
          // 获取节点的 rowid（可能用于作为父节点的标识）
          const nodeRowid = raw.rowid || raw.rowId || raw.id || nodeId

          itemsMapById.set(nodeId, node)
          itemsMapByRowid.set(nodeRowid, node)
        })

        const roots = []
        normalized.forEach((raw) => {
          const nodeId =
            raw.id ||
            raw.itemId ||
            raw.rowid ||
            raw.rowId ||
            raw.code ||
            raw.key
          const node = itemsMapById.get(nodeId)
          if (!node) return

          // 获取父引用字段：优先支持 parentId（按父项 id 关联），兼容 parentid（按父项 rowid 关联）
          const parentid =
            raw.parentid ??
            raw.parentId ??
            raw.parentID ??
            raw.parentCode ??
            raw.parent_code
          const parentIdById = raw.parentId ?? raw.parentID

          // 判定根节点：parentId 为 "-1" 或未提供父引用
          const isRootById = parentIdById === '-1'
          const hasAnyParentRef =
            (parentIdById !== undefined &&
              parentIdById !== null &&
              parentIdById !== '') ||
            (parentid !== undefined && parentid !== null && parentid !== '')

          if (!hasAnyParentRef || isRootById || parentid === '-1') {
            // 作为根节点（父项）
            // 检查是否存在子项指向它（通过 id 或 rowid）
            const hasChildren = normalized.some((item) => {
              const childParentId = item.parentId ?? item.parentID
              const childParentid =
                item.parentid ?? item.parentId ?? item.parentID
              const currentRowid = raw.rowid || raw.rowId || raw.id
              return (
                (childParentId &&
                  childParentId !== '-1' &&
                  childParentId === nodeId) ||
                (childParentid &&
                  childParentid !== '-1' &&
                  childParentid === currentRowid)
              )
            })
            if (hasChildren) {
              node.isCategory = true
            }
            roots.push(node)
          } else {
            // 处理子项：优先使用 parentId -> idMap；否则使用 parentid(rowid) -> rowidMap
            const parentNode =
              (parentIdById &&
                parentIdById !== '-1' &&
                itemsMapById.get(parentIdById)) ||
              (parentid && parentid !== '-1' && itemsMapByRowid.get(parentid))
            if (parentNode) {
              if (!Array.isArray(parentNode.children)) {
                parentNode.children = []
              }
              parentNode.children.push(node)
              // 父项标记为分类（不可操作）
              parentNode.isCategory = true
            } else {
              // 找不到父节点，作为根节点
              roots.push(node)
            }
          }
        })

        return roots.length > 0 ? roots : normalized
      },
    },
  }
</script>

<style scoped lang="scss">
  .fixed-assets-table-container {
    // 分类行样式
    ::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;
      }

      .category-value {
        color: #606266;
        font-weight: normal;
      }
    }

    // 操作按钮样式
    .operation-buttons {
      display: flex;
      justify-content: center;
      gap: 5px;

      .el-button {
        padding: 5px;
        min-width: 24px;
        height: 24px;
        border-radius: 50%;
        background-color: #000;
        color: #fff;
        border: none;

        &:hover {
          background-color: #333;
        }

        i {
          font-size: 14px;
        }
      }
    }

    // 输入框样式
    ::v-deep .el-input__inner {
      border: 1px solid #dcdfe6;
      border-radius: 4px;

      &:focus {
        border-color: #409eff;
      }
    }

    // 日期选择器样式
    ::v-deep .el-date-editor {
      width: 100%;
    }
  }
</style>
