<template>
  <div class="file-uploader-container" :class="isInline ? 'inline' : ''">
    <!-- 上传按钮区域 -->
    <div class="uploadFlex">
      <el-upload
        :action="uploadUrl"
        :headers="headers"
        :show-file-list="false"
        multiple
        :disabled="disabled"
        :on-success="handleUploadSuccess"
        :before-upload="beforeUpload"
      >
        <el-button type="default" :disabled="disabled">上传</el-button>
      </el-upload>
      <el-button
        v-if="!isInline"
        type="default"
        @click="handleMultiDelete"
        :disabled="!selectedIds.length || disabled"
        class="multi-delete-btn"
      >
        删除选中文件
      </el-button>
    </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="文件名" />
      <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"; // 补充缺失的 ArrowDown 图标

// 定义组件 props（放宽类型限制，增加兼容性）
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") || "",
    }),
  },
  // 是否禁用（预览模式）- 默认值：false
  disabled: {
    type: Boolean,
    default: false,
  },
  // 下载接口前缀 - 默认值：系统配置的baseUrl
  downloadBaseUrl: {
    type: String,
    default: () => {
      return windowConfig.baseUrl || "";
    },
  },
});

const emit = defineEmits(["update:modelValue"]);

const selectedIds = ref([]);
const popoverVisible = 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 handleUploadSuccess = (res) => {
  if (res && res.data) {
    safeFileList.value = [...safeFileList.value, res.data]; // 改用 safeFileList
    console.log("上传成功：", res.data);
    ElMessage.success("文件上传成功");
    popoverVisible.value = false;
  }
};

const beforeUpload = (file) => {
  // 可添加文件类型、大小等校验逻辑
  return true;
};

// 选择文件变化
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]; // 改用 safeFileList
      newList.splice(index, 1);
      safeFileList.value = newList; // 改用 safeFileList
      // 删除后关闭popover
      popoverVisible.value = false;
    })
    .catch(() => {});
};

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

// 监听外部文件列表变化（改为监听 safeFileList，无需额外处理）
watch(
  () => safeFileList.value,
  (newVal) => {
    // 空监听，仅保证响应式（safeFileList 已处理类型兼容）
  },
  { deep: true },
);

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

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

// ::v-deep .el-form-item__label {
//   font-weight: 600;
//   color: #509eff !important;
// }
.multi-delete-btn {
  margin-left: 10px;
}
.uploadFlex {
  display: flex;
  margin-bottom: 16px;
}
.inline {
  display: flex;
  align-items: center;
  gap: 10px;
  .uploadFlex {
    display: flex;
    margin-bottom: 0;
  }
}

.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;
}
</style>
