<template>
  <div class="dynamic-table-container">
    <!-- 操作按钮区（新增 + 导入导出 + 自定义头部按钮） -->
    <div
      class="tab-handle"
      v-if="!disabled && (showAddButton || showImportExport)"
    >
      <!-- 新增按钮 -->
      <el-button
        v-if="showAddButton"
        type="primary"
        @click="handleAdd"
        :disabled="disabled"
      >
        {{ addButtonText || "新增" }}
      </el-button>

      <!-- 导入导出功能（直接内置） -->
      <div
        v-if="showImportExport && !disabled"
        class="table-import-export"
        style="margin-left: 12px"
      >
        <!-- 导出按钮 -->
        <el-button
          type="primary"
          @click="handleExport"
          :disabled="!modelValue.length"
          :icon="Download"
        >
          导出
        </el-button>

        <!-- 导入按钮 -->
        <el-upload
          ref="uploadRef"
          class="upload-demo"
          action=""
          :auto-upload="false"
          :on-change="handleImport"
          :show-file-list="false"
          style="margin: 0 12px"
        >
          <template #trigger>
            <el-button type="primary" :icon="Upload"> 导入 </el-button>
          </template>
        </el-upload>
      </div>

      <!-- 顶部自定义按钮插槽（可选） -->
      <slot name="header-actions" />
    </div>

    <!-- 表格上方默认插槽 -->
    <slot></slot>

    <!-- 表格主体 -->
    <el-table
      :data="modelValue"
      style="width: 100%"
      empty-text="暂无数据"
      border
      :disabled="disabled || column?.disabled"
      :scrollbar-always-on="scrollbarAlwaysOn"
    >
      <!-- 序号列 -->
      <el-table-column type="index" fixed="left" width="60" label="序号" />

      <!-- 🌟 有配置headerGroup → 渲染多级表头（按组合并） -->
      <template
        v-if="hasHeaderGroup"
        v-for="group in headerColumnGroups"
        :key="group.key"
      >
        <el-table-column :label="group.label" :align="group.align || 'center'">
          <!-- 二级表头：列渲染逻辑（原生模板，适配Vite编译） -->
          <el-table-column
            v-for="column in group.children"
            :key="column.prop"
            :prop="column.prop"
            :label="column.label"
            :min-width="column.minWidth || 140"
            :align="column.align || 'left'"
          >
            <template #default="scope">
              <template v-if="column.type === 'input'">
                <el-input
                  v-model="scope.row[column.prop]"
                  :placeholder="column.placeholder"
                  :disabled="disabled || column?.disabled"
                  :maxlength="column.maxlength"
                />
              </template>
              <template v-else-if="column.type === 'number'">
                <el-input
                  v-model.number="scope.row[column.prop]"
                  type="number"
                  :placeholder="column.placeholder"
                  :disabled="disabled || column?.disabled"
                  :precision="column.precision"
                  :min="column.min"
                  :max="column.max"
                />
              </template>
              <template v-else-if="column.type === 'textarea'">
                <el-input
                  v-model="scope.row[column.prop]"
                  type="textarea"
                  :placeholder="column.placeholder"
                  :disabled="disabled || column?.disabled"
                  :rows="column.rows || 3"
                  :maxlength="column.maxlength"
                  :show-word-limit="column.showWordLimit || false"
                />
              </template>
              <template v-else-if="column.type === 'select'">
                <el-select
                  v-model="scope.row[column.prop]"
                  :placeholder="column.placeholder"
                  :disabled="disabled || column?.disabled"
                  :multiple="column.multiple || false"
                >
                  <el-option
                    v-for="item in selectOptions?.[column.optionKey] || []"
                    :key="item.key || item.value"
                    :label="item.name || item.label"
                    :value="item.key || item.value"
                  />
                </el-select>
              </template>
              <template v-else-if="column.type === 'radio'">
                <el-radio-group
                  v-model="scope.row[column.prop]"
                  :disabled="disabled || column?.disabled"
                >
                  <el-radio
                    v-for="item in selectOptions?.[column.optionKey] || []"
                    :key="item.key || item.value"
                    :label="item.key || item.value"
                    style="margin-right: 12px"
                  >
                    {{ item.name || item.label }}
                  </el-radio>
                </el-radio-group>
              </template>
              <template
                v-else-if="column.type === 'date' || column.type === 'datetime'"
              >
                <el-date-picker
                  v-model="scope.row[column.prop]"
                  :type="column.type === 'datetime' ? 'datetime' : 'date'"
                  :format="column.format || 'YYYY-MM-DD'"
                  :value-format="column.valueFormat || 'YYYY-MM-DD'"
                  :placeholder="column.placeholder"
                  :disabled="disabled || column?.disabled"
                  style="width: 100%"
                />
              </template>
              <template v-else-if="column.type === 'upload'">
                <FileUploader
                  v-model="scope.row[column.prop]"
                  :isInline="true"
                  :disabled="disabled || column?.disabled"
                />
              </template>
            </template>
          </el-table-column>
        </el-table-column>
      </template>

      <!-- 🌟 无配置headerGroup → 渲染原生单级表头（和原组件完全一致） -->
      <el-table-column
        v-else
        v-for="column in columns"
        :key="column.prop"
        :prop="column.prop"
        :label="column.label"
        :min-width="column.minWidth || 140"
        :align="column.align || 'left'"
      >
        <template #default="scope">
          <template v-if="column.type === 'input'">
            <el-input
              v-model="scope.row[column.prop]"
              :placeholder="column.placeholder"
              :disabled="disabled || column?.disabled"
              :maxlength="column.maxlength"
            />
          </template>
          <template v-else-if="column.type === 'number'">
            <el-input
              v-model.number="scope.row[column.prop]"
              type="number"
              :placeholder="column.placeholder"
              :disabled="disabled || column?.disabled"
              :precision="column.precision"
              :min="column.min"
              :max="column.max"
            />
          </template>
          <template v-else-if="column.type === 'textarea'">
            <el-input
              v-model="scope.row[column.prop]"
              type="textarea"
              :placeholder="column.placeholder"
              :disabled="disabled || column?.disabled"
              :rows="column.rows || 3"
              :maxlength="column.maxlength"
              :show-word-limit="column.showWordLimit || false"
            />
          </template>
          <template v-else-if="column.type === 'select'">
            <el-select
              v-model="scope.row[column.prop]"
              :placeholder="column.placeholder"
              :disabled="disabled || column?.disabled"
              :multiple="column.multiple || false"
            >
              <el-option
                v-for="item in selectOptions?.[column.optionKey] || []"
                :key="item.key || item.value"
                :label="item.name || item.label"
                :value="item.key || item.value"
              />
            </el-select>
          </template>
          <template v-else-if="column.type === 'radio'">
            <el-radio-group
              v-model="scope.row[column.prop]"
              :disabled="disabled || column?.disabled"
            >
              <el-radio
                v-for="item in selectOptions?.[column.optionKey] || []"
                :key="item.key || item.value"
                :label="item.key || item.value"
                style="margin-right: 12px"
              >
                {{ item.name || item.label }}
              </el-radio>
            </el-radio-group>
          </template>
          <template
            v-else-if="column.type === 'date' || column.type === 'datetime'"
          >
            <el-date-picker
              v-model="scope.row[column.prop]"
              :type="column.type === 'datetime' ? 'datetime' : 'date'"
              :format="column.format || 'YYYY-MM-DD'"
              :value-format="column.valueFormat || 'YYYY-MM-DD'"
              :placeholder="column.placeholder"
              :disabled="disabled || column?.disabled"
              style="width: 100%"
            />
          </template>
          <template v-else-if="column.type === 'upload'">
            <FileUploader v-model="scope.row[column.prop]" :isInline="true" />
          </template>
        </template>
      </el-table-column>

      <!-- 操作列 -->
      <el-table-column
        label="操作"
        fixed="right"
        :width="operationColumnWidth"
        :min-width="operationColumnMinWidth"
        v-if="
          !disabled &&
          (showDeleteButton || operationButtons.length > 0 || $slots.operations)
        "
      >
        <template #default="scope">
          <!-- 默认删除按钮 -->
          <el-button
            v-if="showDeleteButton"
            link
            type="danger"
            size="small"
            @click="handleDelete(scope.$index)"
            :disabled="disabled || column?.disabled"
            class="operation-btn"
          >
            删除
          </el-button>
          <!-- 自定义操作按钮 -->
          <el-button
            v-for="(btn, btnIndex) in operationButtons"
            :key="btnIndex"
            :link="btn.link !== false"
            :type="btn.type || 'primary'"
            :size="btn.size || 'small'"
            @click="handleCustomOperation(btn, scope)"
            :disabled="disabled || btn.disabled"
            class="operation-btn"
          >
            {{ btn.text }}
          </el-button>
          <!-- 操作列自定义插槽 -->
          <slot
            name="operations"
            :row="scope.row"
            :index="scope.$index"
            :disabled="disabled || column?.disabled"
          />
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script setup>
import { defineProps, defineEmits, ref, computed } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { Download, Upload } from "@element-plus/icons-vue";
// 请确认项目实际路径，不一致直接修改
import FileUploader from "@/components/FileUploader/index.vue";
// 请确认项目实际路径，不一致直接修改
import { getTableFileData, exportTableFile } from "@/common/tableFileHandle";

// 定义Props
const props = defineProps({
  // 核心双向绑定数据
  modelValue: { type: Array, required: true, default: () => [] },
  // 列配置（headerGroup用于多级表头合并）
  columns: { type: Array, required: true, default: () => [] },
  // 新增行默认值
  defaultRow: { type: Object, default: () => ({}) },
  // 基础配置
  addButtonText: { type: String, default: "新增" },
  disabled: { type: Boolean, default: false },
  selectOptions: { type: Object, default: () => ({}) },
  scrollbarAlwaysOn: { type: Boolean, default: false },
  // 按钮显隐配置
  showAddButton: { type: Boolean, default: true },
  showDeleteButton: { type: Boolean, default: true },
  // 导入导出配置
  showImportExport: { type: Boolean, default: false },
  exportName: { type: String, default: "表格数据" },
  // 自定义操作按钮
  operationButtons: { type: Array, default: () => [] },
  operationColumnWidth: { type: [String, Number], default: "auto" },
  operationColumnMinWidth: { type: [String, Number], default: 60 },
});

// 定义事件
const emit = defineEmits([
  "update:modelValue",
  "add",
  "delete",
  "custom-operation",
  "import-success",
]);

// 导入上传组件Ref
const uploadRef = ref(null);

// 🌟 多级表头开关：是否有列配置了headerGroup（核心判断）
const hasHeaderGroup = computed(() => {
  return props.columns.some((col) => !!col.headerGroup);
});

// 🌟 多级表头分组计算属性：按headerGroup自动分组，保持列原始顺序
const headerColumnGroups = computed(() => {
  const { columns } = props;
  if (!columns.length) return [];

  const groupMap = {};
  columns.forEach((col) => {
    // 无headerGroup用唯一标识，避免分组混乱
    const groupKey = col.headerGroup || `single_${col.prop}`;
    if (!groupMap[groupKey]) {
      groupMap[groupKey] = {
        label: col.headerGroup || col.label,
        key: groupKey,
        children: [],
      };
    }
    groupMap[groupKey].children.push(col);
  });

  // 保持列的原始配置顺序，解决分组后列乱序问题
  const result = [];
  const addedKeys = new Set();
  columns.forEach((col) => {
    const groupKey = col.headerGroup || `single_${col.prop}`;
    if (!addedKeys.has(groupKey)) {
      result.push(groupMap[groupKey]);
      addedKeys.add(groupKey);
    }
  });

  return result;
});

/**
 * 导出数据转换：select/radio的key值转为文字描述
 */
const convertDataForExport = (data) => {
  if (!data || !data.length) return [];
  return data.map((row) => {
    const newRow = { ...row };
    props.columns.forEach((column) => {
      if (column.type === "select" || column.type === "radio") {
        const prop = column.prop;
        const optionKey = column.optionKey;
        const options = props.selectOptions?.[optionKey] || [];
        if (
          newRow[prop] !== undefined &&
          newRow[prop] !== null &&
          newRow[prop] !== ""
        ) {
          // 处理多选
          if (column.multiple && Array.isArray(newRow[prop])) {
            newRow[prop] = newRow[prop]
              .map((key) => {
                const option = options.find(
                  (item) => (item.key || item.value) === key,
                );
                return option ? item.name || item.label : key;
              })
              .join("，");
          } else {
            // 处理单选
            const option = options.find(
              (item) => (item.key || item.value) === newRow[prop],
            );
            newRow[prop] = option ? item.name || item.label : newRow[prop];
          }
        }
      }
    });
    return newRow;
  });
};

/**
 * 导入数据转换：文字描述转回对应的key值
 */
const convertDataForImport = (data) => {
  if (!data || !data.length) return [];
  return data.map((row) => {
    const newRow = { ...row };
    props.columns.forEach((column) => {
      if (column.type === "select" || column.type === "radio") {
        const prop = column.prop;
        const optionKey = column.optionKey;
        const options = props.selectOptions?.[optionKey] || [];
        if (
          newRow[prop] !== undefined &&
          newRow[prop] !== null &&
          newRow[prop] !== ""
        ) {
          // 处理多选
          if (column.multiple) {
            const textList = newRow[prop]
              .split("，")
              .map((item) => item.trim());
            newRow[prop] = textList.map((text) => {
              const option = options.find(
                (item) => (item.name || item.label) === text,
              );
              return option ? item.key || item.value : text;
            });
          } else {
            // 处理单选
            const option = options.find(
              (item) => (item.name || item.label) === newRow[prop],
            );
            newRow[prop] = option ? item.key || item.value : newRow[prop];
          }
        } else {
          newRow[prop] = "";
        }
      }
    });
    return newRow;
  });
};

// 新增行
const handleAdd = () => {
  try {
    const newRow = { ...props.defaultRow };
    const newData = [...props.modelValue, newRow];
    emit("update:modelValue", newData);
    emit("add", newRow);
  } catch (e) {
    console.error("新增行失败:", e);
    ElMessage.error("新增失败，请稍后重试");
  }
};

// 删除行
const handleDelete = (index) => {
  ElMessageBox.confirm("确认删除该项？", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      try {
        const newData = [...props.modelValue];
        newData.splice(index, 1);
        emit("update:modelValue", newData);
        emit("delete", index);
        ElMessage.success("删除成功");
      } catch (e) {
        console.error("删除行失败:", e);
        ElMessage.error("删除失败，请稍后重试");
      }
    })
    .catch(() => {});
};

// 自定义操作按钮点击
const handleCustomOperation = (btn, scope) => {
  if (btn.click) {
    try {
      btn.click(scope.row, scope.$index);
    } catch (e) {
      console.error("自定义按钮点击失败:", e);
      ElMessage.error("操作执行失败，请稍后重试");
    }
  }
  emit("custom-operation", btn, scope.row, scope.$index);
};

// 导出表格数据
const handleExport = () => {
  try {
    const exportData = convertDataForExport(props.modelValue);
    exportTableFile(exportData, props.columns, "", props.exportName);
    ElMessage.success("导出成功");
  } catch (e) {
    console.error("导出失败:", e);
    ElMessage.error("导出失败，请稍后重试");
  }
};

// 导入表格数据
const handleImport = (file) => {
  uploadRef.value?.clearFiles();
  getTableFileData(file, props.columns)
    .then((rawImportData) => {
      const convertedData = convertDataForImport(rawImportData);
      handleImportSuccess(convertedData);
      ElMessage.success(`导入成功，共${convertedData.length}条数据`);
    })
    .catch((e) => {
      console.error("导入失败:", e);
      ElMessage.error("导入失败，请检查文件格式是否正确");
    });
};

// 导入成功后数据处理
const handleImportSuccess = (importData) => {
  try {
    const newData = [...props.modelValue, ...importData];
    emit("update:modelValue", newData);
    emit("import-success", importData);
  } catch (e) {
    console.error("导入数据合并失败:", e);
    ElMessage.error("导入数据处理失败，请稍后重试");
  }
};
</script>

<style scoped lang="less">
.dynamic-table-container {
  width: 100%;
}

.tab-handle {
  margin-bottom: 10px;
  text-align: left;
  display: flex;
  align-items: center;

  :deep(.el-button) {
    margin-right: 8px;
  }
}

.table-import-export {
  display: inline-flex;
  align-items: center;

  :deep(.el-button) {
    margin-right: 8px;
  }
}

.operation-btn {
  margin-right: 4px;
}

:deep(.el-table) {
  --el-table-header-text-color: #303133;
  --el-table-row-hover-bg-color: #f8f9fa;
}

:deep(.el-upload),
:deep(.el-textarea),
:deep(.el-date-picker) {
  width: 100%;
}
</style>
