<template>
  <div class="sa-upload-image">
    <div class="upload-container sa-flex sa-flex-wrap">
      <!-- 已上传的图片列表 -->
      <sa-draggable
        v-if="imageList.length > 0"
        v-model="imageList"
        :animation="300"
        handle=".sortable-drag"
        item-key="url"
        @end="handleSort"
        class="sa-flex sa-flex-wrap"
      >
        <template #item="{ element, index }">
          <div
            class="image-item"
            :class="{ 'compact-mode': compact }"
            :style="{ width: size + 'px', height: size + 'px' }"
          >
            <el-image
              :src="element"
              fit="cover"
              :preview-src-list="compact ? [] : imageList"
              :initial-index="compact ? 0 : index"
              :preview-teleported="true"
              @click="compact ? previewImage(element, index) : null"
              :style="{ cursor: compact ? 'pointer' : 'default' }"
            >
              <template #error>
                <div class="image-error">
                  <el-icon><Picture /></el-icon>
                </div>
              </template>
            </el-image>
            <div class="image-mask" :class="{ 'compact-mask': compact }">
              <template v-if="compact">
                <el-icon @click.stop="removeImage(index)" title="删除" size="12"
                  ><Delete
                /></el-icon>
              </template>
              <template v-else>
                <el-icon class="sortable-drag" title="拖拽排序" size="24"><Rank /></el-icon>
                <el-icon @click="previewImage(element, index)" title="预览" size="24"
                  ><ZoomIn
                /></el-icon>
                <el-icon @click="removeImage(index)" title="删除" size="24"><Delete /></el-icon>
              </template>
            </div>
          </div>
        </template>
      </sa-draggable>

      <!-- 上传按钮 -->
      <div
        v-if="!maxCount || imageList.length < maxCount"
        class="upload-trigger"
        :class="{ 'compact-trigger': compact }"
        :style="{ width: size + 'px', height: size + 'px' }"
        @click="handleUpload"
      >
        <el-icon class="upload-icon" :size="compact ? 16 : 24"><Plus /></el-icon>
        <div v-if="!compact" class="upload-text">{{ placeholder || '上传图片' }}</div>
      </div>

      <!-- 隐藏的文件输入框 -->
      <input
        ref="fileInputRef"
        type="file"
        :accept="acceptString"
        :multiple="multiple"
        style="display: none"
        @change="handleFileSelect"
      />
    </div>

    <!-- 提示信息 -->
    <div v-if="showTip" class="upload-tip">
      <span v-if="maxCount">最多上传{{ maxCount }}张，</span>
      <span v-if="accept && accept.length">支持{{ accept.join('、') }}格式，</span>
      <span v-if="maxSize">单张图片不超过{{ maxSize }}MB</span>
    </div>

    <!-- 图片预览弹窗 -->
    <el-image-viewer
      v-if="previewVisible"
      :url-list="previewImageList"
      :initial-index="previewInitialIndex"
      :infinite="false"
      :hide-on-click-modal="true"
      :teleported="true"
      :z-index="3000"
      @close="closePreview"
    />
  </div>
</template>

<script>
  import { ref, computed, watch } from 'vue';
  import { ElMessage, ElImageViewer } from 'element-plus';
  import { Picture, Plus, Rank, ZoomIn, Delete } from '@element-plus/icons-vue';
  import SaDraggable from 'vuedraggable';
  import adminApi from '@/app/admin/api';

  export default {
    name: 'SaUploadImage',
    components: {
      Picture,
      Plus,
      Rank,
      ZoomIn,
      Delete,
      SaDraggable,
      ElImageViewer,
    },
  };
</script>

<script setup>
  const props = defineProps({
    modelValue: {
      type: Array,
      default: () => [],
    },
    // 是否直传，默认为true
    directUpload: {
      type: Boolean,
      default: true,
    },
    // 最大上传数量
    maxCount: {
      type: Number,
      default: 0,
    },
    // 支持的文件格式
    accept: {
      type: Array,
      default: () => ['jpg', 'jpeg', 'png'],
    },
    // 最大文件大小(MB)
    maxSize: {
      type: Number,
      default: 2,
    },
    // 是否支持多选
    multiple: {
      type: Boolean,
      default: true,
    },
    // 图片尺寸
    size: {
      type: Number,
      default: 100,
    },
    // 占位符文本
    placeholder: {
      type: String,
      default: '',
    },
    // 是否显示提示信息
    showTip: {
      type: Boolean,
      default: true,
    },
    // 精简模式
    compact: {
      type: Boolean,
      default: false,
    },
  });

  const emit = defineEmits(['update:modelValue', 'change']);

  // 文件输入框引用
  const fileInputRef = ref();

  // 图片列表
  const imageList = ref([...props.modelValue]);

  // 计算接受的文件类型字符串
  const acceptString = computed(() => {
    return props.accept.map((type) => `.${type}`).join(',');
  });

  // 监听外部数据变化
  watch(
    () => props.modelValue,
    (newValue) => {
      imageList.value = [...newValue];
    },
    { deep: true },
  );

  // 监听内部数据变化
  watch(
    imageList,
    (newValue) => {
      emit('update:modelValue', newValue);
      emit('change', newValue);
    },
    { deep: true },
  );

  // 处理上传点击
  const handleUpload = () => {
    if (props.directUpload) {
      // 直传模式，直接打开文件选择
      fileInputRef.value?.click();
    } else {
      // 非直传模式，打开文件管理弹窗
      openFileManager();
    }
  };

  // 处理文件选择
  const handleFileSelect = async (event) => {
    const files = Array.from(event.target.files);

    if (!files.length) return;

    // 检查数量限制
    if (props.maxCount && imageList.value.length + files.length > props.maxCount) {
      ElMessage.warning(`最多只能上传${props.maxCount}张图片`);
      return;
    }

    // 验证文件
    const validFiles = [];
    for (const file of files) {
      if (validateFile(file)) {
        validFiles.push(file);
      }
    }

    if (validFiles.length === 0) return;

    // 上传文件
    try {
      const uploadPromises = validFiles.map((file) => uploadFile(file));
      const results = await Promise.all(uploadPromises);

      // 添加成功上传的图片
      results.forEach((result) => {
        if (result.success) {
          imageList.value.push(result.url);
        }
      });

      ElMessage.success(`成功上传${results.filter((r) => r.success).length}张图片`);
    } catch (error) {
      ElMessage.error('上传失败：' + error.message);
    }

    // 清空文件输入框
    event.target.value = '';
  };

  // 验证文件
  const validateFile = (file) => {
    // 检查文件类型
    const fileExtension = file.name.split('.').pop().toLowerCase();
    if (!props.accept.includes(fileExtension)) {
      ElMessage.warning(`不支持${fileExtension}格式，请选择${props.accept.join('、')}格式的图片`);
      return false;
    }

    // 检查文件大小
    const fileSizeMB = file.size / 1024 / 1024;
    if (props.maxSize && fileSizeMB > props.maxSize) {
      ElMessage.warning(`图片大小不能超过${props.maxSize}MB`);
      return false;
    }

    return true;
  };

  // 上传文件
  const uploadFile = async (file) => {
    try {
      const response = await adminApi.file.upload({}, file);
      if (response.code == '200') {
        return {
          success: true,
          url: response.data.url,
        };
      } else {
        throw new Error(response.msg || '上传失败');
      }
    } catch (error) {
      console.error('上传文件失败:', error);
      return {
        success: false,
        error: error.message,
      };
    }
  };

  // 打开文件管理器（非直传模式）
  const openFileManager = () => {
    // 这里可以集成现有的文件管理器组件
    console.log('打开文件管理器');
    ElMessage.info('文件管理器功能待实现');
  };

  // 图片预览状态
  const previewVisible = ref(false);
  const previewImageUrl = ref('');
  const previewImageList = ref([]);
  const previewInitialIndex = ref(0);

  // 预览图片
  const previewImage = (url, index = 0) => {
    previewImageUrl.value = url;
    previewImageList.value = [...imageList.value];
    previewInitialIndex.value = index;
    previewVisible.value = true;
  };

  // 关闭预览
  const closePreview = () => {
    previewVisible.value = false;
    previewImageUrl.value = '';
    previewImageList.value = [];
    previewInitialIndex.value = 0;
  };

  // 删除图片
  const removeImage = (index) => {
    imageList.value.splice(index, 1);
  };

  // 处理拖拽排序
  const handleSort = () => {
    // 拖拽排序后自动触发 watch 更新
    console.log('图片排序已更新');
  };
</script>

<style lang="scss" scoped>
  .sa-upload-image {
    .upload-container {
      gap: 8px;
    }

    .image-item {
      position: relative;
      border-radius: 6px;
      overflow: hidden;
      border: 1px solid #dcdfe6;

      .el-image {
        width: 100%;
        height: 100%;
      }

      .image-error {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 100%;
        background: #f5f7fa;
        color: #909399;
      }

      .image-mask {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.6);
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        opacity: 0;
        transition: opacity 0.3s;

        .el-icon {
          color: white;
          font-size: 16px;
          cursor: pointer;
          padding: 4px;
          border-radius: 2px;
          transition: background-color 0.3s;

          &:hover {
            background: rgba(255, 255, 255, 0.2);
          }

          &.sortable-drag {
            cursor: move;
          }
        }
      }

      &:hover .image-mask {
        opacity: 1;
      }
    }

    .upload-trigger {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      border: 2px dashed #dcdfe6;
      border-radius: 6px;
      cursor: pointer;
      transition: border-color 0.3s;
      background: #fafafa;

      &:hover {
        // 使用系统主色调
        border-color: var(--el-color-primary);
      }

      .upload-icon {
        font-size: 24px;
        color: #8c939d;
        margin-bottom: 4px;
      }

      .upload-text {
        font-size: 12px;
        color: #8c939d;
      }
    }

    .upload-tip {
      margin-top: 8px;
      font-size: 12px;
      color: #909399;
      line-height: 1.4;
    }

    /* 精简模式样式 */
    .compact-mode {
      border: 1px solid #dcdfe6;
      border-radius: 4px;

      &:hover {
        border-color: var(--el-color-primary);
      }
    }

    .compact-mask {
      background: transparent;
      pointer-events: none;

      .el-icon {
        position: absolute;
        top: 2px;
        right: 2px;
        background: rgba(0, 0, 0, 0.8);
        border-radius: 50%;
        padding: 1px;
        pointer-events: auto;
        width: 16px;
        height: 16px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
      }
    }

    .compact-trigger {
      border: 1px dashed #dcdfe6;
      border-radius: 4px;
      background: #fafafa;
      transition: all 0.3s;

      &:hover {
        border-color: var(--el-color-primary);
        background: var(--el-color-primary-light-9);
      }

      .upload-icon {
        color: #8c939d;
      }

      &:hover .upload-icon {
        color: var(--el-color-primary);
      }
    }
  }
</style>
