<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { Modal, Upload } from 'ant-design-vue';
import type { UploadFile } from 'ant-design-vue';

// 恢复使用原有的上传接口
import { uploadFile } from '#/api/core/upload';
import { Icon } from '#/components/icon';

// 定义接口
interface FileItem {
  uid: string;
  name: string;
  status: 'uploading' | 'done' | 'error';
  url: string;
}

// 定义props
interface Props {
  modelValue: string[];
  multiple?: boolean;
  maxCount?: number;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => [],
  multiple: true,
  maxCount: 9,
});

const emit = defineEmits<{
  'update:modelValue': [value: string[]];
}>();

const fileList = ref<FileItem[]>([]);

// 初始化fileList
const initFileList = () => {
  fileList.value = props.modelValue.map((url) => ({
    uid: url,
    name: url.split('/').pop() || 'file',
    status: 'done' as const,
    url,
  }));
};

// 初始化
initFileList();

// 监听外部modelValue变化，同步到fileList
watch(() => props.modelValue, (newVal) => {
  const currentUrls = fileList.value.filter(file => file.status === 'done').map(file => file.url);
  if (JSON.stringify(newVal) !== JSON.stringify(currentUrls)) {
    fileList.value = newVal.map((url) => ({
      uid: url,
      name: url.split('/').pop() || 'file',
      status: 'done' as const,
      url,
    }));
  }
}, { deep: true });

// 统一通过updateModelValue函数更新modelValue
const updateModelValue = () => {
  const urls = fileList.value
    .filter((file) => file.status === 'done' && file.url)
    .map((file) => file.url);
  emit('update:modelValue', urls);
};

// 使用原有的uploadFile接口
const customRequest = async (options: any) => {
  const { file, onProgress, onSuccess, onError } = options;

  // 创建上传中的文件项
  const uploadingFile: FileItem = {
    uid: file.uid,
    name: file.name,
    status: 'uploading',
    url: '',
  };

  fileList.value = [...fileList.value, uploadingFile];

  try {
    // 使用原有的uploadFile接口
    const res = await uploadFile({
      file: file,
    });

    // 更新文件状态为完成
    const updatedFileList = fileList.value.map(item =>
      item.uid === file.uid
        ? { ...item, status: 'done' as const, url: res.url }
        : item
    );

    fileList.value = updatedFileList;
    updateModelValue();
    onSuccess(res);
  } catch (error) {
    console.error('上传失败', error);
    // 更新文件状态为错误
    const updatedFileList = fileList.value.map(item =>
      item.uid === file.uid
        ? { ...item, status: 'error' as const }
        : item
    );

    fileList.value = updatedFileList;
    onError(error);
  }
};

// 处理文件删除
const handleRemove = (file: UploadFile) => {
  fileList.value = fileList.value.filter((item) => item.uid !== file.uid);
  updateModelValue();
};

// 预览功能
const previewVisible = ref(false);
const previewImage = ref('');
const previewTitle = ref('');

const handlePreview = async (file: UploadFile) => {
  previewImage.value = file.url || '';
  previewVisible.value = true;
  previewTitle.value = file.name || file.url?.split('/').pop() || '';
};

// 计算是否显示上传按钮
const showUploadButton = computed(() =>
  props.multiple
    ? fileList.value.length < props.maxCount
    : fileList.value.length === 0,
);
</script>

<template>
  <div>
    <Upload
      :file-list="fileList"
      :custom-request="customRequest"
      :multiple="multiple"
      :max-count="maxCount"
      :show-upload-list="{
        showPreviewIcon: true,
        showRemoveIcon: true,
      }"
      list-type="picture-card"
      @remove="handleRemove"
      @preview="handlePreview"
    >
      <div v-if="showUploadButton" class="upload-button">
        <!-- 恢复使用Icon组件 -->
        <Icon icon="ant-design:plus-outlined" />
        <div class="ant-upload-text">上传图片</div>
      </div>
    </Upload>

    <Modal
      v-model:visible="previewVisible"
      :title="previewTitle"
      footer=""
      width="60%"
    >
      <img alt="预览图片" style="width: 100%" :src="previewImage" />
    </Modal>
  </div>
</template>

<style lang="less" scoped>
.upload-button {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  cursor: pointer;
}
</style>
