<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>
      <slot name="header-actions" />
    </div>

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

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

      <!-- 多级表头渲染 -->
      <template
        v-if="hasHeaderGroup"
        v-for="group in headerColumnGroups"
        :key="group.key"
      >
        <el-table-column :label="group.label" :align="group.align || 'center'">
          <el-table-column
            v-for="col in group.children"
            :key="col.prop"
            :prop="col.prop"
            :label="col.label"
            :min-width="col.minWidth || 140"
            :align="col.align || 'left'"
          >
            <template #default="scope">
              <!-- Input 类型 -->
              <template v-if="col.type === 'input'">
                <el-input
                  v-model="scope.row[col.prop]"
                  :placeholder="col.placeholder"
                  :disabled="disabled || col.disabled"
                  :maxlength="col.maxlength"
                  size="small"
                />
              </template>

              <!-- Textarea 类型 -->
              <template v-else-if="col.type === 'textarea'">
                <el-input
                  v-model="scope.row[col.prop]"
                  type="textarea"
                  :placeholder="col.placeholder || '请输入内容'"
                  :disabled="disabled || col.disabled"
                  :rows="col.rows || 3"
                  :maxlength="col.maxlength"
                  :show-word-limit="col.showWordLimit || false"
                  style="width: 100%"
                  size="small"
                />
              </template>

              <!-- Select 类型 -->
              <template v-else-if="col.type === 'select'">
                <el-select
                  v-model="scope.row[col.prop]"
                  :placeholder="col.placeholder || '请选择'"
                  :disabled="disabled || col.disabled"
                  :multiple="col.multiple || false"
                >
                  <el-option
                    v-for="item in mergedSelectOptions[col.optionKey] || []"
                    :key="item.key || item.value"
                    :label="item.name || item.label"
                    :value="item.key || item.value"
                  />
                  <el-option
                    v-if="!mergedSelectOptions[col.optionKey]?.length"
                    disabled
                    label="暂无可选数据"
                    value=""
                  />
                </el-select>
              </template>

              <!-- Number 类型 -->
              <template v-else-if="col.type === 'number'">
                <el-input
                  v-model.number="scope.row[col.prop]"
                  type="number"
                  :placeholder="col.placeholder"
                  :disabled="disabled || col.disabled"
                  :precision="col.precision"
                  :min="col.min"
                  :max="col.max"
                  size="small"
                />
              </template>

              <!-- Radio 类型 -->
              <template v-else-if="col.type === 'radio'">
                <el-radio-group
                  v-model="scope.row[col.prop]"
                  :disabled="disabled || col.disabled"
                >
                  <el-radio
                    v-for="item in mergedSelectOptions[col.optionKey] || []"
                    :key="item.key || item.value"
                    :label="item.key || item.value"
                    style="margin-right: 12px"
                  >
                    {{ item.name || item.label }}
                  </el-radio>
                  <span v-if="!mergedSelectOptions[col.optionKey]?.length">
                    暂无可选数据
                  </span>
                </el-radio-group>
              </template>

              <!-- Date/DateTime 类型 -->
              <template
                v-else-if="col.type === 'date' || col.type === 'datetime'"
              >
                <el-date-picker
                  v-model="scope.row[col.prop]"
                  :type="col.type === 'datetime' ? 'datetime' : 'date'"
                  :format="col.format || 'YYYY-MM-DD'"
                  :value-format="col.valueFormat || 'YYYY-MM-DD'"
                  :placeholder="col.placeholder"
                  :disabled="disabled || col.disabled"
                  style="width: 100%"
                  size="small"
                />
              </template>

              <!-- Upload 上传类型（核心适配） -->
              <template v-else-if="col.type === 'upload'">
                <FileUploader
                  v-model="scope.row[col.prop]"
                  :isInline="col.isInline ?? true"
                />
              </template>
            </template>
          </el-table-column>
        </el-table-column>
      </template>

      <!-- 单级表头渲染（核心） -->
      <el-table-column
        v-else
        v-for="col in columns"
        :key="col.prop"
        :prop="col.prop"
        :label="col.label"
        :min-width="col.minWidth || 140"
        :align="col.align || 'left'"
      >
        <template #default="scope">
          <!-- Input 类型 -->
          <template v-if="col.type === 'input'">
            <el-input
              v-model="scope.row[col.prop]"
              :placeholder="col.placeholder"
              :disabled="disabled || col.disabled"
              :maxlength="col.maxlength"
              size="small"
            />
          </template>

          <!-- Textarea 类型 -->
          <template v-else-if="col.type === 'textarea'">
            <el-input
              v-model="scope.row[col.prop]"
              type="textarea"
              :placeholder="col.placeholder || '请输入内容'"
              :disabled="disabled || col.disabled"
              :rows="col.rows || 3"
              :maxlength="col.maxlength"
              :show-word-limit="col.showWordLimit || false"
              style="width: 100%"
              size="small"
            />
          </template>

          <!-- Select 类型（适配全局下拉选项） -->
          <template v-else-if="col.type === 'select'">
            <el-select
              v-model="scope.row[col.prop]"
              :placeholder="col.placeholder || '请选择'"
              :disabled="disabled || col.disabled"
              :multiple="col.multiple || false"
            >
              <el-option
                v-for="item in mergedSelectOptions[col.optionKey] || []"
                :key="item.key || item.value"
                :label="item.name || item.label"
                :value="item.key || item.value"
              />
              <el-option
                v-if="!mergedSelectOptions[col.optionKey]?.length"
                disabled
                label="暂无可选数据"
                value=""
              />
            </el-select>
          </template>

          <!-- Number 类型 -->
          <template v-else-if="col.type === 'number'">
            <el-input
              v-model.number="scope.row[col.prop]"
              type="number"
              :placeholder="col.placeholder"
              :disabled="disabled || col.disabled"
              :precision="col.precision"
              :min="col.min"
              :max="col.max"
              size="small"
            />
          </template>

          <!-- Radio 类型 -->
          <template v-else-if="col.type === 'radio'">
            <el-radio-group
              v-model="scope.row[col.prop]"
              :disabled="disabled || col.disabled"
            >
              <el-radio
                v-for="item in mergedSelectOptions[col.optionKey] || []"
                :key="item.key || item.value"
                :label="item.key || item.value"
                style="margin-right: 12px"
              >
                {{ item.name || item.label }}
              </el-radio>
              <span v-if="!mergedSelectOptions[col.optionKey]?.length">
                暂无可选数据
              </span>
            </el-radio-group>
          </template>

          <!-- Date/DateTime 类型 -->
          <template v-else-if="col.type === 'date' || col.type === 'datetime'">
            <el-date-picker
              v-model="scope.row[col.prop]"
              :type="col.type === 'datetime' ? 'datetime' : 'date'"
              :format="col.format || 'YYYY-MM-DD'"
              :value-format="col.valueFormat || 'YYYY-MM-DD'"
              :placeholder="col.placeholder"
              :disabled="disabled || col.disabled"
              style="width: 100%"
              size="small"
            />
          </template>

          <!-- Upload 上传类型（核心适配你的业务） -->
          <template v-else-if="col.type === 'upload'">
            <FileUploader
              v-model="scope.row[col.prop]"
              :isInline="col.isInline ?? true"
            />
          </template>
        </template>
      </el-table-column>

      <!-- 操作列 -->
      <el-table-column
        label="操作"
        fixed="right"
        align="center"
        :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"
            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"
          />
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script setup>
import {
  defineProps,
  defineEmits,
  ref,
  computed,
  onMounted,
  getCurrentInstance,
} from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
// 引入文件上传组件（适配你的项目路径）
import FileUploader from "@/components/FileUploader/index.vue";

// 获取全局实例（用于接口请求/全局配置）
const { proxy } = getCurrentInstance();

// 定义Props
const props = defineProps({
  modelValue: { type: Array, required: true, default: () => [] },
  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",
]);

// 全局下拉选项（从sessionStorage读取，适配你的业务）
const globalOptions = ref({});
// 默认上传配置（适配你的项目接口）
const defaultUploadUrl = ref("");
const defaultUploadHeaders = ref({});
const defaultDownloadUrl = ref("");

// 初始化全局配置
onMounted(() => {
  try {
    // 1. 读取全局下拉选项
    const storageData = sessionStorage.getItem("resourceData");
    globalOptions.value = storageData ? JSON.parse(storageData) : {};

    // 2. 初始化默认上传配置（适配你的项目）
    const baseUrl = proxy?.$config?.baseUrl || "";
    defaultUploadUrl.value = `${baseUrl}/api/file/upload`;
    defaultDownloadUrl.value = baseUrl;
    defaultUploadHeaders.value = {
      Authorization: sessionStorage.getItem("authToken") || "",
    };
  } catch (e) {
    console.error("初始化全局配置失败：", e);
    globalOptions.value = {};
  }
});

// 合并下拉选项：父组件传入 > 全局配置
const mergedSelectOptions = computed(() => {
  return {
    ...globalOptions.value,
    ...props.selectOptions,
  };
});

// 多级表头相关计算属性
const hasHeaderGroup = computed(() => {
  return props.columns.some((col) => !!col.headerGroup);
});

const headerColumnGroups = computed(() => {
  const { columns } = props;
  if (!columns.length) return [];

  const groupMap = {};
  columns.forEach((col) => {
    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;
});

// 新增行（适配默认行数据，初始化upload字段为数组）
const handleAdd = () => {
  try {
    const newRow = { ...props.defaultRow };
    // 初始化各类型字段默认值
    props.columns.forEach((col) => {
      // Textarea 初始化为空字符串
      if (col.type === "textarea" && newRow[col.prop] === undefined) {
        newRow[col.prop] = "";
      }
      // Upload 初始化为空数组
      if (col.type === "upload" && newRow[col.prop] === undefined) {
        newRow[col.prop] = [];
      }
      // Select/Input 初始化为空字符串
      if (
        ["input", "select", "number"].includes(col.type) &&
        newRow[col.prop] === undefined
      ) {
        newRow[col.prop] = "";
      }
    });
    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);
};
</script>

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

.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;
  --el-table-border-color: #ebeef5;
}

/* 适配各组件样式 */
:deep(.el-input__textarea) {
  width: 100%;
  resize: vertical;
}

:deep(.el-upload),
:deep(.el-textarea),
:deep(.el-date-picker),
:deep(.el-select) {
  width: 100%;
}

/* 小尺寸组件适配 */
:deep(.el-input--small) {
  --el-input-height: 32px;
}

:deep(.el-table-cell) {
  padding: 8px 0;
}
</style>
