<template>
  <div class="p-2">
    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
      <div v-show="showSearch" class="mb-[10px]">
        <el-card shadow="hover">
          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
            <el-form-item label="等级" prop="levelNumber">
              <el-input v-model="queryParams.levelNumber" placeholder="请输入等级" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="小盲" prop="smallBlind">
              <el-input v-model="queryParams.smallBlind" placeholder="请输入小盲" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="大盲" prop="bigBlind">
              <el-input v-model="queryParams.bigBlind" placeholder="请输入大盲" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="前注" prop="ante">
              <el-input v-model="queryParams.ante" placeholder="请输入前注" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="盲注分钟" prop="durationMinutes">
              <el-input v-model="queryParams.durationMinutes" placeholder="请输入盲注分钟" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </div>
    </transition>

    <div class="blind-levels-container">
      <el-card shadow="never" class="blind-levels-card">
        <template #header>
          <el-row :gutter="10" class="mb8">
            <el-col :span="1.5">
              <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['physical:blindLevels:add']">新增</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['physical:blindLevels:edit']">修改</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['physical:blindLevels:remove']">删除</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['physical:blindLevels:export']">导出</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button type="primary" plain icon="Upload" @click="handleImport" v-hasPermi="['physical:blindLevels:import']">导入</el-button>
            </el-col>
            <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
          </el-row>
        </template>

        <el-table v-loading="loading" border :data="blindLevelsList" @selection-change="handleSelectionChange" row-key="id" :row-class-name="tableRowClassName">
          <el-table-column type="selection" width="55" align="center" :reserve-selection="true" />
          <el-table-column label="显示级别" align="center" width="120">
            <template #default="scope">
              <span v-if="scope.row.isBreak === 1" style="color: #e6a23c; font-weight: bold">{{ getDisplayLevel(scope.row) }}</span>
              <span v-else>{{ getDisplayLevel(scope.row) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="小盲" align="center">
            <template #default="scope">
              <div class="stepper-cell">
                <el-button size="small" text @click="stepValue(scope.row, 'smallBlind', -1)">−</el-button>
                <span class="stepper-value">{{ scope.row.smallBlind ?? 0 }}</span>
                <el-button size="small" text @click="stepValue(scope.row, 'smallBlind', 1)">+</el-button>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="大盲" align="center">
            <template #default="scope">
              <div class="stepper-cell">
                <el-button size="small" text @click="stepValue(scope.row, 'bigBlind', -1)">−</el-button>
                <span class="stepper-value">{{ scope.row.bigBlind ?? 0 }}</span>
                <el-button size="small" text @click="stepValue(scope.row, 'bigBlind', 1)">+</el-button>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="前注" align="center">
            <template #default="scope">
              <div class="stepper-cell">
                <el-button size="small" text @click="stepValue(scope.row, 'ante', -1)">−</el-button>
                <span class="stepper-value">{{ scope.row.ante ?? 0 }}</span>
                <el-button size="small" text @click="stepValue(scope.row, 'ante', 1)">+</el-button>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="盲注分钟" align="center" width="140">
            <template #default="scope">
              <div class="stepper-cell">
                <el-button size="small" text @click="stepValue(scope.row, 'durationMinutes', -1)">−</el-button>
                <span class="stepper-value">{{ scope.row.durationMinutes ?? 0 }}</span>
                <el-button size="small" text @click="stepValue(scope.row, 'durationMinutes', 1)">+</el-button>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="休息级别" align="center" width="120">
            <template #default="scope">
              <el-select v-model="scope.row.isBreak" size="small" style="width: 100px">
                <el-option label="否" :value="0" />
                <el-option label="是" :value="1" />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column label="休息分钟" align="center" width="120">
            <template #default="scope">
              <div class="stepper-cell">
                <el-button size="small" text :disabled="scope.row.isBreak !== 1" @click="stepValue(scope.row, 'breakDurationMinutes', -1)">−</el-button>
                <span class="stepper-value" :style="{ opacity: scope.row.isBreak !== 1 ? 0.4 : 1 }">{{ scope.row.breakDurationMinutes ?? 0 }}</span>
                <el-button size="small" text :disabled="scope.row.isBreak !== 1" @click="stepValue(scope.row, 'breakDurationMinutes', 1)">+</el-button>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="名次" align="center" width="120">
            <template #default="scope">
              <div class="stepper-cell">
                <el-button size="small" text @click="stepValue(scope.row, 'displayOrder', -1)">−</el-button>
                <span class="stepper-value">{{ scope.row.displayOrder ?? 0 }}</span>
                <el-button size="small" text @click="stepValue(scope.row, 'displayOrder', 1)">+</el-button>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="140">
            <template #default="scope">
              <el-button link type="primary" size="small" :loading="insertLoading" @click="handleInsertAfter(scope.row)">插入</el-button>
              <el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>

        <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />

        <div class="blind-levels-footer">
          <el-button type="primary" :loading="saveLoading" @click="handleBatchSave">保存</el-button>
          <el-button @click="handleClose">关闭</el-button>
        </div>
      </el-card>
    </div>

    <!-- 添加或修改线下盲注等级对话框 -->
    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
      <el-form ref="blindLevelsFormRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="所属盲注" prop="name">
          <el-input v-model="form.name" disabled />
        </el-form-item>
        <el-form-item label="等级" prop="levelNumber">
          <el-input v-model="form.levelNumber" placeholder="请输入等级" />
        </el-form-item>
        <el-form-item label="小盲" prop="smallBlind">
          <el-input v-model="form.smallBlind" placeholder="请输入小盲" />
        </el-form-item>
        <el-form-item label="大盲" prop="bigBlind">
          <el-input v-model="form.bigBlind" placeholder="请输入大盲" />
        </el-form-item>
        <el-form-item label="前注" prop="ante">
          <el-input v-model="form.ante" placeholder="请输入前注" />
        </el-form-item>
        <el-form-item label="盲注分钟" prop="durationMinutes">
          <el-input v-model="form.durationMinutes" placeholder="请输入盲注分钟" />
        </el-form-item>
        <el-form-item label="名次" prop="displayOrder">
          <el-input v-model="form.displayOrder" placeholder="请输入名次" />
        </el-form-item>
        <el-form-item label="是否休息" prop="isBreak">
          <el-radio-group v-model="form.isBreak">
            <el-radio :label="1">是</el-radio>
            <el-radio :label="0">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="休息时长" prop="breakDurationMinutes">
          <el-input v-model="form.breakDurationMinutes" placeholder="请输入休息时长" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 导入对话框 -->
    <el-dialog :title="importDialog.title" v-model="importDialog.visible" width="500px" append-to-body>
      <el-upload
        ref="uploadRef"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="importDialog.headers"
        :action="importDialog.url"
        :disabled="importDialog.isUploading"
        :on-change="handleFileChange"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <template #tip>
          <div class="el-upload__tip text-center">
            <div class="el-upload__tip">
              <el-checkbox v-model="importDialog.updateSupport" />是否更新已经存在的数据
            </div>
            <span>仅允许导入xls、xlsx格式文件。</span>
            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="handleDownloadTemplate">下载模板</el-link>
          </div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitFileForm">确 定</el-button>
          <el-button @click="importDialog.visible = false; uploadFile.value = null; uploadRef.value?.clearFiles()">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="BlindLevels" lang="ts">
import {
  listBlindLevels,
  getBlindLevels,
  delBlindLevels,
  addBlindLevels,
  updateBlindLevels,
  downloadImportTemplate,
  importData,
  insertAfter,
  batchSave
} from '@/api/system/physical/blindLevels';
import { BlindLevelsVO, BlindLevelsQuery, BlindLevelsForm } from '@/api/system/physical/blindLevels/types';
import { parseTime } from '@/utils/dateUtils';
import { useBlindStructureInfo } from '@/api/system/business/levels/useBlindStructureId';
import { getToken } from '@/utils/auth';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;

const blindLevelsList = ref<BlindLevelsVO[]>([]);
const buttonLoading = ref(false);
const saveLoading = ref(false);
const insertLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);

const queryFormRef = ref<ElFormInstance>();
const blindLevelsFormRef = ref<ElFormInstance>();
const uploadRef = ref<ElUploadInstance>();
const uploadFile = ref<File | null>(null);
const rowErrors = ref<Map<string | number, string[]>>(new Map());

const props = defineProps({
  blindStructureId: {
    type: [Number, String],
    required: false,
    default: null
  },
  name: {
    type: String,
    required: false,
    default: ''
  }
});

const { info } = useBlindStructureInfo(props);

const currentId = ref<number | string | null>(null);
const currentName = ref('');

const dialog = reactive<DialogOption>({
  visible: false,
  title: ''
});

const importDialog = reactive({
  visible: false,
  title: '导入盲注等级数据',
  isUploading: false,
  updateSupport: false,
  headers: { Authorization: 'Bearer ' + getToken() },
  url: import.meta.env.VITE_APP_BASE_API + '/physical/blindLevels/importData'
});

const initFormData: BlindLevelsForm = {
  id: undefined,
  name: undefined,
  blindStructureId: undefined,
  levelNumber: undefined,
  smallBlind: undefined,
  bigBlind: undefined,
  ante: undefined,
  durationMinutes: undefined,
  createdAt: undefined,
  updatedAt: undefined,
  createUserId: undefined,
  updateUserId: undefined,
  isBreak: 0,
  breakDurationMinutes: undefined,
  remark: undefined,
  displayOrder: undefined
};
const data = reactive<PageData<BlindLevelsForm, BlindLevelsQuery>>({
  form: { ...initFormData },
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    blindStructureId: undefined,
    levelNumber: undefined,
    smallBlind: undefined,
    bigBlind: undefined,
    ante: undefined,
    durationMinutes: undefined,
    createdAt: undefined,
    updatedAt: undefined,
    createUserId: undefined,
    updateUserId: undefined,
    isBreak: undefined,
    breakDurationMinutes: undefined,
    displayOrder: undefined,
    params: {},
    // ✅ 核心修复：强制按levelNumber升序排序，解决插入后位置错乱问题
    orderByColumn: 'levelNumber',
    isAsc: 'asc'
  },
  rules: {
    id: [{ required: true, message: '不能为空', trigger: 'blur' }],
    levelNumber: [{ required: true, message: '级别编号不能为空', trigger: 'blur' }],
    smallBlind: [{ required: true, message: '小盲金额不能为空', trigger: 'blur' }],
    bigBlind: [{ required: true, message: '大盲金额不能为空', trigger: 'blur' }],
    durationMinutes: [{ required: true, message: '持续时间不能为空', trigger: 'blur' }]
  }
});

const { queryParams, form, rules } = toRefs(data);

/** 查询线下盲注等级列表 */
const getList = async () => {
  loading.value = true;
  const res = await listBlindLevels(queryParams.value);
  // 确保 isBreak 为数字类型，避免 select 显示 false/true，并按 levelNumber 升序排序
  // 统一排序逻辑：与线下盲注表保持一致，按级别编号排序而非ID排序
  blindLevelsList.value = (res.rows || [])
    .map((item: any) => ({
      ...item,
      isBreak: item.isBreak === true || item.isBreak === 1 ? 1 : 0
    }))
    .sort((a, b) => {
      const levelA = a.levelNumber || 0;
      const levelB = b.levelNumber || 0;
      return levelA - levelB;
    });
  total.value = res.total;
  loading.value = false;
};

const sortListByLevelNumber = () => {
  blindLevelsList.value.sort((a, b) => {
    const levelA = a.levelNumber || 0;
    const levelB = b.levelNumber || 0;
    return levelA - levelB;
  });
};

/** 计算显示级别：休息行不占级别，非休息行连续计算（如：1、2、休息(第2级后)、3、4...） */
const getDisplayLevel = (row: BlindLevelsVO): string | number => {
  const idx = blindLevelsList.value.findIndex((r) => r.id === row.id);
  if (idx === -1) return row.levelNumber;
  const nonBreakBefore = blindLevelsList.value.slice(0, idx).filter((r) => r.isBreak !== 1).length;
  if (row.isBreak === 1) {
    return `休息(第${nonBreakBefore}级后)`;
  }
  return nonBreakBefore + 1;
};

/** 取消按钮 */
const cancel = () => {
  reset();
  dialog.visible = false;
};

/** 表单重置 */
const reset = () => {
  form.value = { ...initFormData };
  blindLevelsFormRef.value?.resetFields();
};

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
};

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields();
  handleQuery();
};

/** 多选框选中数据 */
const handleSelectionChange = (selection: BlindLevelsVO[]) => {
  ids.value = selection.map((item) => item.id);
  single.value = selection.length != 1;
  multiple.value = !selection.length;
};

/** 新增按钮操作 */
const handleAdd = () => {
  reset();
  dialog.visible = true;
  dialog.title = '添加';
};

/** 修改按钮操作 */
const handleUpdate = async (row?: BlindLevelsVO) => {
  reset();
  const _id = row?.id || ids.value[0];
  const res = await getBlindLevels(_id);
  Object.assign(form.value, res.data);
  dialog.visible = true;
  dialog.title = '修改';
};

/** 提交按钮 */
const submitForm = () => {
  blindLevelsFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      buttonLoading.value = true;
      if (form.value.id) {
        await updateBlindLevels(form.value).finally(() => (buttonLoading.value = false));
      } else {
        await addBlindLevels(form.value).finally(() => (buttonLoading.value = false));
      }
      proxy?.$modal.msgSuccess('操作成功');
      dialog.visible = false;
      await getList();
    }
  });
};

/** 删除按钮操作 */
const handleDelete = async (row?: BlindLevelsVO) => {
  // 行内删除：未保存的临时数据，直接移除不弹框
  if (row && (row as any)._isNew) {
    const idx = blindLevelsList.value.findIndex((r) => r.id === row.id);
    if (idx !== -1) {
      blindLevelsList.value.splice(idx, 1);
    }
    proxy?.$modal.msgSuccess('删除成功');
    return;
  }
  // 已保存数据或批量删除：弹确认后调API
  const _ids = row?.id || ids.value;
  await proxy?.$modal.confirm('是否确认删除编号为"' + _ids + '"的数据项？').finally(() => (loading.value = false));
  await delBlindLevels(_ids);
  proxy?.$modal.msgSuccess('删除成功');
  await getList();
};

/** 导出按钮操作 */
const handleExport = () => {
  proxy?.download(
    'physical/blindLevels/export',
    {
      ...queryParams.value
    },
    `盲注等级详情${parseTime(new Date(), '{y}{m}{d}{h}{i}{s}')}.xlsx`
  );
};

/** 导入按钮操作 */
const handleImport = () => {
  importDialog.visible = true;
};

/** 下载模板 */
const handleDownloadTemplate = async () => {
  try {
    const response = await downloadImportTemplate();
    const blobData = new Blob([response.data || response], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    });
    const urlBlob = window.URL.createObjectURL(blobData);
    const link = document.createElement('a');
    link.href = urlBlob;
    link.setAttribute('download', '盲注等级模板.xlsx');
    document.body.appendChild(link);
    link.click();
    setTimeout(() => {
      link.remove();
      window.URL.revokeObjectURL(urlBlob);
    }, 0);
  } catch (error) {
    console.error('Download error:', error);
    ElMessage.error('下载失败，请重试');
  }
};

/** 文件上传中处理 */
const handleFileUploadProgress = () => {
  importDialog.isUploading = true;
};

/** 文件上传成功处理 */
const handleFileSuccess = async (response: any, file: any) => {
  importDialog.isUploading = false;
  uploadRef.value?.clearFiles();
  importDialog.visible = false;

  if (response.code === 200) {
    proxy?.$modal.msgSuccess('导入成功');
    await getList();
  } else {
    proxy?.$modal.msgError(response.msg || '导入失败');
  }
};

/** 文件选择变化 */
const handleFileChange = (file: any) => {
  uploadFile.value = file.raw;
};

/** 提交上传文件 */
const submitFileForm = () => {
  if (!uploadFile.value) {
    proxy?.$modal.msgError('请先选择文件');
    return;
  }

  if (!currentId.value) {
    proxy?.$modal.msgError('盲注结构ID不能为空');
    return;
  }

  importDialog.isUploading = true;
  importData(uploadFile.value, currentId.value)
    .then((response: any) => {
      importDialog.isUploading = false;
      uploadFile.value = null;
      uploadRef.value?.clearFiles();
      importDialog.visible = false;

      if (response.code === 200) {
        proxy?.$modal.msgSuccess('导入成功');
        getList();
      } else {
        proxy?.$modal.msgError(response.msg || '导入失败');
      }
    })
    .catch((error) => {
      importDialog.isUploading = false;
      proxy?.$modal.msgError('导入失败，请重试');
      console.error('Import error:', error);
    });
};

/** 行内步进器增减（步长=1） */
const stepValue = (row: BlindLevelsVO, field: 'smallBlind' | 'bigBlind' | 'ante' | 'durationMinutes' | 'breakDurationMinutes' | 'displayOrder', delta: number) => {
  const val = (row[field] as number) || 0;
  (row as any)[field] = Math.max(0, val + delta);
};

/** 表格行样式（有错误的行标红） */
const tableRowClassName = ({ row }: { row: BlindLevelsVO }) => {
  if (rowErrors.value.has(row.id)) {
    return 'row-error';
  }
  return '';
};

/** 校验所有行数据 */
const validateRows = (): string[] => {
  const allErrors: string[] = [];
  rowErrors.value.clear();

  blindLevelsList.value.forEach((row) => {
    const errors: string[] = [];
    if (!row.levelNumber || row.levelNumber <= 0) {
      errors.push(`级别${row.levelNumber || '?'}：级别编号不能为空`);
    }
    if (row.smallBlind === null || row.smallBlind === undefined || row.smallBlind < 0) {
      errors.push(`级别${row.levelNumber || '?'}：小盲金额不能为空`);
    }
    if (row.bigBlind === null || row.bigBlind === undefined || row.bigBlind < 0) {
      errors.push(`级别${row.levelNumber || '?'}：大盲金额不能为空`);
    }
    if (row.bigBlind !== null && row.bigBlind !== undefined && row.smallBlind !== null && row.smallBlind !== undefined && row.bigBlind < row.smallBlind) {
      errors.push(`级别${row.levelNumber || '?'}：大盲金额不能小于小盲金额`);
    }
    if (row.durationMinutes === null || row.durationMinutes === undefined || row.durationMinutes < 0) {
      errors.push(`级别${row.levelNumber || '?'}：本级别持续时间（分钟）不能为空`);
    }
    if (row.isBreak === 1 && (!row.breakDurationMinutes || row.breakDurationMinutes <= 0)) {
      errors.push(`级别${row.levelNumber || '?'}：休息级别为“是”时，休息分钟不能为0`);
    }
    if (errors.length > 0) {
      rowErrors.value.set(row.id, errors);
      allErrors.push(...errors);
    }
  });

  return allErrors;
};

/** 在指定级别后插入（默认全0，本地插入不刷新列表） */
const handleInsertAfter = async (row: BlindLevelsVO) => {
  if (insertLoading.value) return; // 防止重复点击
  insertLoading.value = true;
  const newLevelNumber = (row.levelNumber || 0) + 1;
  const newLevel: BlindLevelsForm = {
    id: undefined,
    blindStructureId: currentId.value as string | number,
    levelNumber: newLevelNumber,
    smallBlind: 0,
    bigBlind: 0,
    ante: 0,
    durationMinutes: 0,
    isBreak: 0,
    breakDurationMinutes: 0,
    displayOrder: 0
  };
  try {
    await insertAfter(newLevel, row.levelNumber);

    // 关键修复：插入新级别后，将后续所有记录的levelNumber+1，避免编号重复
    blindLevelsList.value.forEach((item) => {
      if (item.levelNumber >= newLevelNumber && item.id !== row.id) {
        item.levelNumber += 1;
      }
    });

    // 本地插入新行到正确位置
    const idx = blindLevelsList.value.findIndex((r) => r.id === row.id);
    if (idx !== -1) {
      blindLevelsList.value.splice(idx + 1, 0, { ...newLevel, id: Date.now(), _isNew: true } as any);
      // 按levelNumber排序确保顺序正确
      sortListByLevelNumber();
    }

    proxy?.$modal.msgSuccess(`成功在第${row.levelNumber}级后插入第${newLevelNumber}级`);
  } catch (error) {
    proxy?.$modal.msgError('插入失败，请重试');
    console.error('Insert after error:', error);
  } finally {
    insertLoading.value = false;
  }
};

/** 批量保存（先拉取全部数据，合并当前页编辑后一起提交） */
const handleBatchSave = async () => {
  if (!blindLevelsList.value || blindLevelsList.value.length === 0) {
    proxy?.$modal.msgError('没有数据可保存');
    return;
  }

  // 校验当前页
  const errors = validateRows();
  if (errors.length > 0) {
    proxy?.$modal.msgError(errors[0]);
    return;
  }

  saveLoading.value = true;
  try {
    // ✅ 关键修复：只收集已存在记录的编辑内容（不包括新插入的临时记录）
    // 原因：新插入的记录已经通过 insertAfter() API 在后端创建了，
    //       如果再提交会导致重复数据！
    const localEdits = new Map<string | number, BlindLevelsVO>();

    blindLevelsList.value.forEach((row) => {
      if (row.id && !(row as any)._isNew) {
        // 只收集已存在的记录，忽略 _isNew 标记的临时记录
        localEdits.set(row.id, row);
      }
    });

    // 拉取全部数据（不分页，强制按levelNumber排序）
    const allRes = await listBlindLevels({
      ...queryParams.value,
      pageNum: 1,
      pageSize: 9999999,
      orderByColumn: 'levelNumber',
      isAsc: 'asc'
    });
    let allRows: BlindLevelsVO[] = (allRes.rows || []).map((item: any) => ({
      ...item,
      isBreak: item.isBreak === true || item.isBreak === 1 ? 1 : 0
    }));

    // 用本地编辑覆盖全量数据中对应的行（包括对新插入记录的编辑）
    allRows.forEach((row) => {
      if (row.id && localEdits.has(row.id)) {
        Object.assign(row, localEdits.get(row.id));
      }
    });

    // ✅ 特殊处理：将用户对新插入记录的编辑合并到后端返回的对应记录上
    blindLevelsList.value.forEach((localRow) => {
      if ((localRow as any)._isNew && localRow.levelNumber) {
        // 找到后端数据中相同 levelNumber 的记录（就是刚才 insertAfter 创建的）
        const backendRow = allRows.find(r => r.levelNumber === localRow.levelNumber);
        if (backendRow) {
          // 将用户的编辑内容合并到后端记录上
          Object.assign(backendRow, {
            smallBlind: localRow.smallBlind,
            bigBlind: localRow.bigBlind,
            ante: localRow.ante,
            durationMinutes: localRow.durationMinutes,
            isBreak: localRow.isBreak,
            breakDurationMinutes: localRow.breakDurationMinutes
          });
        }
      }
    });

    // ✅ 保存前自动修正levelNumber，确保连续且不重复
    allRows.sort((a, b) => (a.levelNumber || 0) - (b.levelNumber || 0));
    let expectedLevel = 1;
    allRows.forEach((row) => {
      row.levelNumber = expectedLevel++;
    });

    console.log('💾 准备保存的数据:', allRows); // 调试日志
    await batchSave(allRows as BlindLevelsForm[]);
    proxy?.$modal.msgSuccess('保存成功');
    await getList();
  } catch (error) {
    proxy?.$modal.msgError('保存失败，请重试');
    console.error('Batch save error:', error);
  } finally {
    saveLoading.value = false;
  }
};

/** 关闭 */
const handleClose = () => {
  // 如果在弹窗中使用，关闭弹窗
  const parentDialog = (proxy?.$parent as any)?.$parent;
  if (parentDialog && parentDialog.$options?.name !== 'BlindLevels') {
    // 尝试找到父级 dialog 并关闭
    let el: any = proxy?.$el;
    while (el) {
      if (el.classList && el.classList.contains('el-dialog')) {
        const closeBtn = el.querySelector('.el-dialog__headerbtn');
        if (closeBtn) closeBtn.click();
        break;
      }
      el = el.parentElement;
    }
  }
};

onMounted(() => {
  const id = currentId;
  if (id !== undefined) {
    queryParams.value.blindStructureId = currentId.value;
    initFormData.name = currentName.value;
  }
  getList();

  // 将保存/关闭按钮移到父级 dialog 的 footer 区域，使其固定不随滚动
  nextTick(() => {
    const footerEl = (proxy?.$el as HTMLElement)?.querySelector('.blind-levels-footer') as HTMLElement;
    if (!footerEl) return;
    let dialogEl: HTMLElement | null = footerEl.closest('.el-dialog');
    if (!dialogEl) {
      let el: HTMLElement | null = footerEl.parentElement;
      while (el) {
        if (el.classList?.contains('el-dialog')) {
          dialogEl = el;
          break;
        }
        el = el.parentElement;
      }
    }
    if (dialogEl) {
      let dialogFooter = dialogEl.querySelector('.el-dialog__footer') as HTMLElement;
      if (!dialogFooter) {
        dialogFooter = document.createElement('div');
        dialogFooter.className = 'el-dialog__footer';
        dialogEl.appendChild(dialogFooter);
      }
      // 清空旧的 footer 内容，避免重复
      dialogFooter.innerHTML = '';
      dialogFooter.appendChild(footerEl);
      footerEl.style.position = '';
      footerEl.style.bottom = '';
      footerEl.style.background = '';
      footerEl.style.borderRadius = '';
      footerEl.style.boxShadow = '';
      footerEl.style.zIndex = '';
      footerEl.style.padding = '10px 0 0';
    }
  });
});

watch(
  () => info(),
  (newInfo) => {
    if (newInfo.id !== currentId.value || newInfo.name !== currentName.value) {
      currentId.value = newInfo.id;
      currentName.value = newInfo.name;
      initFormData.blindStructureId = newInfo.id;
      initFormData.name = newInfo.name;
      queryParams.value.blindStructureId = newInfo.id;
      if (newInfo.id !== null) {
        getList();
      }
    }
  },
  { immediate: true }
);

// ✅ 暴露刷新方法给父组件调用
defineExpose({
  refreshList: getList
});
</script>

<style scoped>
.blind-levels-container {
  height: 100%;
}
.blind-levels-card {
  height: 100%;
  overflow: auto;
}
.blind-levels-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 10px 0 0;
}
.stepper-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
.stepper-cell .el-button {
  padding: 2px 8px;
  font-size: 14px;
  min-width: 28px;
  color: #606266;
}
.stepper-cell .el-button:hover:not(:disabled) {
  color: #409eff;
}
.stepper-cell .el-button:disabled {
  color: #c0c4cc;
  cursor: not-allowed;
}
.stepper-value {
  display: inline-block;
  min-width: 60px;
  text-align: center;
  padding: 4px 12px;
  background: #f5f7fa;
  border-radius: 4px;
  font-size: 14px;
  color: #606266;
}
:deep(.row-error) {
  background-color: #fef0f0 !important;
}
:deep(.row-error td) {
  color: #f56c6c;
}
</style>
