<template>
  <div class="file-uploader">
    <el-upload
      class="file-uploader__upload"
      :http-request="customUploadRequest"
      :on-success="handleUploadSuccess"
      :on-remove="handleRemove"
      :file-list="fileList"
      list-type="picture-card"
      :limit="limit"
      :show-file-list="true"
      :auto-upload="true"
      :disabled="readonly"
      :accept="accept"
    >
      <el-icon v-if="fileList.length < limit"><Plus /></el-icon>
    </el-upload>
    <el-image-viewer v-if="previewShow" :url-list="previewList" :initial-index="previewIndex" @close="previewShow = false" />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import { CommonUpload } from '@/apis/index';

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => [],
  },
  ossUrl: {
    type: String,
    default: 'http://gov-cloud.oss-cn-chengdu.aliyuncs.com/',
  },
  limit: {
    type: Number,
    default: 5,
  },
  accept: {
    type: String,
    default: 'image/*',
  },
  readonly: {
    type: Boolean,
    default: false,
  },
});
const emit = defineEmits(['update:modelValue']);

// 构造 el-upload 所需 file-list
const fileList = computed(() => {
  return props.modelValue.map((path, idx) => ({
    name: `image_${idx}`,
    url: props.ossUrl + path,
    uid: `${idx}`,
  }));
});

// 预览
const previewShow = ref(false);
const previewList = computed(() => fileList.value.map((item) => item.url));
const previewIndex = ref(0);

// 上传请求内部实现
const customUploadRequest = async ({ file, onSuccess, onError }) => {
  const formData = new FormData();
  formData.append('file', file);
  try {
    const res = await CommonUpload(formData);
    // 假设后端返回 { code:200, data: { url: 'relative/path.jpg' } }
    onSuccess(res, file);
  } catch (err) {
    onError(err);
  }
};

// 上传成功回调，推入 modelValue
function handleUploadSuccess(res) {
  const relative = res.data?.url;
  if (relative) {
    const newArr = [...props.modelValue, relative];
    emit('update:modelValue', newArr);
  }
}

// 删除图片
function handleRemove(file) {
  const fullUrl = file.url;
  const relative = fullUrl.replace(props.ossUrl, '');
  const newArr = props.modelValue.filter((path) => path !== relative);
  emit('update:modelValue', newArr);
}

// 点击预览
function handlePreview(file) {
  const idx = fileList.value.findIndex((item) => item.uid === file.uid);
  if (idx !== -1) {
    previewIndex.value = idx;
    previewShow.value = true;
  }
}
</script>

<style scoped>
.file-uploader {
  display: flex;
  flex-wrap: wrap;
}
.file-uploader__upload {
  margin-right: 16px;
}
</style>
