<template>
  <div class="file-uploader-container" :class="isInline ? 'inline' : ''">
    <!-- 上传按钮区域 -->
    <div class="uploadFlex">
      <el-upload
        :timeout="300000"
        :action="uploadUrl"
        :headers="headers"
        :show-file-list="false"
        multiple
        :disabled="disabled || uploading"
        :on-success="handleUploadSuccess"
        :on-error="handleUploadError"
        :before-upload="beforeUpload"
        :on-progress="handleProgress"
      >
        <el-button type="default" :disabled="disabled || uploading">
          <span v-if="uploading">上传中...</span>
          <span v-else>上传</span>
        </el-button>
      </el-upload>

      <!-- 进度条 -->
      <div v-if="showProgress" class="progress-container">
        <el-progress
          :percentage="uploadPercentage"
          stroke-width="6"
          size="small"
        />
      </div>

      <el-button
        v-if="!isInline"
        type="default"
        @click="handleMultiDelete"
        :disabled="!selectedIds.length || disabled"
        class="multi-delete-btn"
      >
        删除选中文件
      </el-button>
      <slot name="actions"></slot>
    </div>

    <!-- 文件列表表格 -->
    <el-table
      v-if="!isInline"
      :data="safeFileList"
      style="width: 100%"
      empty-text="暂无数据"
      border
      @selection-change="handleSelectionChange"
      class="file-table"
    >
      <el-table-column type="selection" width="55" :disabled="disabled" />
      <el-table-column prop="originalname" label="文件名" />
      <!-- 新增：自定义可配置列 -->
      <template
        v-for="(col, index) in customColumns"
        :key="`custom-col-${index}`"
      >
        <el-table-column
          :prop="col.prop"
          :label="col.label"
          :width="col.width"
          :fixed="col.fixed"
          :align="col.align || 'left'"
        >
          <template #default="{ row, $index }">
            <!-- 输入框 -->
            <el-input
              v-if="col.type === 'input'"
              v-model="row[col.prop]"
              :disabled="disabled || col.disabled"
              :placeholder="col.placeholder || `请输入${col.label}`"
              size="small"
              @change="handleCustomColChange(row, col.prop, $index)"
            />
            <el-input
              v-else-if="col.type === 'textarea'"
              v-model="row[col.prop]"
              :disabled="disabled || col.disabled"
              :placeholder="col.placeholder || `请输入${col.label}`"
              :rows="col.rows || 2"
              type="textarea"
              size="small"
              @change="handleCustomColChange(row, col.prop, $index)"
            />
            <!-- 日期选择器 -->
            <el-date-picker
              v-else-if="col.type === 'date'"
              v-model="row[col.prop]"
              :disabled="disabled || col.disabled"
              :format="col.format || 'YYYY-MM-DD'"
              :value-format="col.valueFormat || 'YYYY-MM-DD'"
              :placeholder="col.placeholder || `请选择${col.label}`"
              size="small"
              @change="handleCustomColChange(row, col.prop, $index)"
            />
            <!-- 日期时间选择器 -->
            <el-date-picker
              v-else-if="col.type === 'datetime'"
              v-model="row[col.prop]"
              :disabled="disabled || col.disabled"
              type="datetime"
              :format="col.format || 'YYYY-MM-DD HH:mm:ss'"
              :value-format="col.valueFormat || 'YYYY-MM-DD HH:mm:ss'"
              :placeholder="col.placeholder || `请选择${col.label}`"
              size="small"
              @change="handleCustomColChange(row, col.prop, $index)"
            />
            <!-- 下拉选择器 -->
            <el-select
              v-else-if="col.type === 'select'"
              v-model="row[col.prop]"
              :disabled="disabled || col.disabled"
              :placeholder="col.placeholder || `请选择${col.label}`"
              size="small"
              @change="handleCustomColChange(row, col.prop, $index)"
            >
              <el-option
                v-for="option in col.options || []"
                :key="option.value"
                :label="option.label"
                :value="option.value"
              />
            </el-select>
            <!-- 字典选择器 CommonSelector -->
            <CommonSelector
              v-else-if="col.type === 'dictSelect'"
              v-model="row[col.prop]"
              :dictName="col.dictName"
              :disabled="disabled || col.disabled"
              @change="handleCustomColChange(row, col.prop, $index)"
            />
            <!-- 自定义插槽（最高优先级） -->
            <slot
              v-else
              :name="`custom-col-${col.prop}`"
              :row="row"
              :index="$index"
            >
              <!-- 默认显示字段值 -->
              <span>{{ row[col.prop] || "-" }}</span>
            </slot>
          </template>
        </el-table-column>
      </template>
      <el-table-column prop="updatedAt" label="上传时间">
        <template #default="{ row }">
          <span>{{ formatDate(row.updatedAt) }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="size" label="大小">
        <template #default="{ row }">
          <span>{{ row.size }} MB</span>
        </template>
      </el-table-column>

      <!-- 操作列 -->
      <el-table-column fixed="right" label="操作" width="100">
        <template #default="{ row, $index }">
          <span class="download-btn" @click="handleDownload(row)">下载</span>
          <el-button
            link
            type="danger"
            @click="handleDelete($index)"
            :disabled="disabled"
            class="delete-btn"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <div v-else class="inline-file-wrapper">
      <el-popover
        v-model:visible="popoverVisible"
        placement="bottom-start"
        width="420"
        trigger="hover"
        :disabled="safeFileList.length === 0 || disabled"
        popper-class="file-popover"
      >
        <!-- 弹窗内容 -->
        <template #default>
          <div class="file-popover-content">
            <!-- 无文件提示 -->
            <div v-if="safeFileList.length === 0" class="empty-file-tip">
              暂无上传文件
            </div>

            <!-- 文件列表 -->
            <div v-else class="file-list">
              <div
                v-for="(file, index) in safeFileList"
                :key="file.id || index"
                class="file-item"
              >
                <!-- 文件名 -->
                <div class="file-name">
                  <el-icon class="file-icon"><Document /></el-icon>
                  <span class="name-text" :title="file.originalname">{{
                    file.originalname
                  }}</span>
                </div>

                <!-- 操作按钮 -->
                <div class="file-actions">
                  <div
                    link
                    type="primary"
                    size="small"
                    @click.stop="handleDownload(file)"
                    class="download-action"
                    :disabled="false"
                  >
                    <el-icon><Download /></el-icon>
                    下载
                  </div>

                  <el-button
                    link
                    type="danger"
                    size="small"
                    @click.stop="handleDelete(index)"
                    :disabled="disabled"
                    class="delete-action"
                  >
                    <el-icon><Delete /></el-icon>
                    删除
                  </el-button>
                </div>
              </div>
            </div>
          </div>
        </template>

        <!-- 触发元素（美观的文件数量展示） -->
        <template #reference>
          <div class="inline-file">
            <div class="file-count">
              <span class="count-num">{{ safeFileList.length }}</span>
              <span class="count-text">个文件</span>
            </div>
            <el-icon class="upload-icon"><ArrowDown /></el-icon>
          </div>
        </template>
      </el-popover>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, computed } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import moment from "moment";
import windowConfig from "@/window";
// 引入需要的图标
import { Document, Download, Delete, ArrowDown } from "@element-plus/icons-vue";
// 引入 CommonSelector 组件
import CommonSelector from "@/components/CommonSelector.vue";

// 定义组件 props（新增 customColumns 配置）
const props = defineProps({
  modelValue: {
    type: [Array, String, Number],
    default: () => [],
    required: true,
  },
  label: {
    type: String,
    default: "文件上传",
  },
  isInline: {
    type: Boolean,
    default: false,
  },
  uploadUrl: {
    type: String,
    default: () => {
      return windowConfig.baseUrl + "/api/file/upload";
    },
  },
  headers: {
    type: Object,
    default: () => ({
      Authorization: sessionStorage.getItem("authToken") || "",
    }),
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  downloadBaseUrl: {
    type: String,
    default: () => {
      return windowConfig.baseUrl || "";
    },
  },
  // 新增：自定义列配置
  customColumns: {
    type: Array,
    default: () => [],
    /**
     * 列配置项说明：
     * @param {string} prop - 字段名（必填）
     * @param {string} label - 列标题（必填）
     * @param {string} type - 组件类型：input/textarea/date/datetime/select/dictSelect（默认显示文本）
     * @param {number} width - 列宽度
     * @param {string} fixed - 是否固定列：left/right
     * @param {string} align - 对齐方式：left/center/right
     * @param {boolean} disabled - 是否禁用该列编辑
     * @param {string} placeholder - 占位提示
     * @param {string} format - 日期格式化（仅date/datetime）
     * @param {string} valueFormat - 日期值格式化（仅date/datetime）
     * @param {Array} options - 下拉选项（仅select），格式：[{label: '选项1', value: '1'}, ...]
     * @param {string} dictName - 字典名称（仅dictSelect），用于 CommonSelector 组件
     */
  },
});

const emit = defineEmits([
  "update:modelValue",
  // 新增：自定义列值变化事件
  "custom-col-change",
]);

const selectedIds = ref([]);
const popoverVisible = ref(false);

// ========== 上传进度 & loading 状态 ==========
const uploading = ref(false); // 上传中
const uploadPercentage = ref(0); // 进度百分比
const showProgress = ref(false); // 是否显示进度条

// 核心：安全处理文件列表，将非数组值转为空数组
const safeFileList = computed({
  get() {
    return Array.isArray(props.modelValue) ? props.modelValue : [];
  },
  set(value) {
    emit("update:modelValue", Array.isArray(value) ? value : []);
  },
});

// 格式化日期
const formatDate = (date) => {
  return date ? moment(date).format("YYYY-MM-DD HH:mm:SS") : "";
};

// 上传前
const beforeUpload = (file) => {
  uploading.value = true;
  uploadPercentage.value = 0;
  showProgress.value = true;
  return true;
};

// 上传进度
const handleProgress = (event, file, fileList) => {
  uploadPercentage.value = Math.floor(event.percent);
};

// 文件上传成功处理
const handleUploadSuccess = (res) => {
  if (res && res.data) {
    safeFileList.value = [...safeFileList.value, res.data];
    ElMessage.success("文件上传成功");
    popoverVisible.value = false;
  }
  finishUpload();
};

// 上传失败
const handleUploadError = () => {
  ElMessage.error("文件上传失败");
  finishUpload();
};

// 结束上传
const finishUpload = () => {
  uploading.value = false;
  uploadPercentage.value = 100;
  setTimeout(() => {
    showProgress.value = false;
  }, 500);
};

// 选择文件变化
const handleSelectionChange = (datas) => {
  selectedIds.value = datas.map((item) => item.id);
};

// 下载文件
const handleDownload = (row) => {
  if (!row.id) {
    ElMessage.warning("文件ID不存在，无法下载");
    return;
  }
  if (!props.downloadBaseUrl) {
    ElMessage.warning("下载地址配置异常，请联系管理员");
    return;
  }
  const a = document.createElement("a");
  a.href = `${props.downloadBaseUrl}/api/file/download/${row.id}`;
  a.download = row.originalname;
  document.body.appendChild(a);
  a.click();
  a.remove();
};

// 删除单个文件
const handleDelete = (index) => {
  ElMessageBox.confirm("确认删除该项？", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      const newList = [...safeFileList.value];
      newList.splice(index, 1);
      safeFileList.value = newList;
      popoverVisible.value = false;
    })
    .catch(() => {});
};

// 批量删除文件
const handleMultiDelete = () => {
  ElMessageBox.confirm("确认删除选中数据？", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      const newList = safeFileList.value.filter(
        (item) => !selectedIds.value.includes(item.id),
      );
      safeFileList.value = newList;
      selectedIds.value = [];
    })
    .catch(() => {});
};

// 新增：自定义列值变化处理
const handleCustomColChange = (row, prop, index) => {
  // 触发自定义列变化事件，向外传递修改后的数据
  emit("custom-col-change", {
    row, // 整行数据
    prop, // 修改的字段名
    value: row[prop], // 修改后的值
    index, // 行索引
  });
  // 更新文件列表（保证响应式）
  safeFileList.value = [...safeFileList.value];
};

// 监听外部文件列表变化
watch(
  () => safeFileList.value,
  (newVal) => {},
  { deep: true },
);

// 监听禁用状态变化，关闭popover
watch(
  () => props.disabled,
  (newVal) => {
    if (newVal) {
      popoverVisible.value = false;
    }
  },
);
</script>

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

.multi-delete-btn {
  margin-left: 10px;
}
.uploadFlex {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
  gap: 12px;
}
.inline {
  display: flex;
  align-items: center;
  gap: 10px;
  .uploadFlex {
    display: flex;
    margin-bottom: 0;
  }
}

// 进度条容器
.progress-container {
  flex: 1;
  max-width: 200px;
}

.inline-file-wrapper {
  flex: 1;
  margin-left: 10px;
}

.inline-file {
  display: flex;
  align-items: center;
  padding: 3px 12px;
  background: #f5f7fa;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  justify-content: space-between;
}
.inline-file:hover {
  background: #e8f4ff;
  border-color: #c6e2ff;
}

.upload-icon {
  color: #409eff;
  font-size: 16px;
  margin-right: 8px;
}

.file-count {
  display: flex;
  align-items: baseline;
}
.count-num {
  font-size: 18px;
  font-weight: 600;
  color: #409eff;
  margin-right: 4px;
}
.count-text {
  font-size: 14px;
  color: #606266;
}

:deep(.file-popover) {
  padding: 0;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.file-popover-content {
  padding: 12px;
}

.empty-file-tip {
  text-align: center;
  padding: 20px 0;
  color: #909399;
  font-size: 14px;
}

.file-list {
  max-height: 300px;
  overflow-y: auto;
}

.file-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px dashed #f0f0f0;
}
.file-item:last-child {
  border-bottom: none;
}

.file-name {
  display: flex;
  align-items: center;
  flex: 1;
  overflow: hidden;
}
.file-icon {
  color: #409eff;
  font-size: 14px;
  margin-right: 8px;
}
.name-text {
  font-size: 14px;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-actions {
  display: flex;
  gap: 8px;
}

.download-action {
  display: flex;
  color: #409eff;
  cursor: pointer;
}
.download-action,
.delete-action {
  padding: 0;
  font-size: 12px;
}
:deep(.download-action .el-icon),
:deep(.delete-action .el-icon) {
  margin-right: 4px;
  font-size: 12px;
}

.file-table {
  --el-table-header-text-color: #303133;
  --el-table-row-hover-bg-color: #f5f7fa;
}

.download-btn {
  cursor: pointer;
  color: #409eff;
  margin-right: 10px;
  user-select: none;
}
.download-btn:hover {
  color: #66b1ff;
}

.delete-btn {
  padding: 0;
}

:deep(.el-table__header) {
  font-weight: 600;
}
:deep(.el-button--link) {
  padding: 0;
}

:deep(.file-list::-webkit-scrollbar) {
  width: 6px;
}
:deep(.file-list::-webkit-scrollbar-track) {
  background: #f1f1f1;
  border-radius: 3px;
}
:deep(.file-list::-webkit-scrollbar-thumb) {
  background: #c1c1c1;
  border-radius: 3px;
}
:deep(.file-list::-webkit-scrollbar-thumb:hover) {
  background: #a8a8a8;
}

// 新增：自定义列组件样式优化
:deep(.el-table .el-input),
:deep(.el-table .el-date-picker),
:deep(.el-table .el-select) {
  width: 100%;
}
:deep(.el-table .el-input__wrapper) {
  padding: 0 8px;
}
</style>
