<template>
    <div class="clearfix">
        <a-upload list-type="picture-card" :multiple="multiple" v-model:file-list="fileList" @preview="handlePreview"
            @change="handleChange" :customRequest="handleCustomRequest" :beforeUpload="beforeUpload">
            <div v-if="fileList.length < fileNumber">
                <plus-outlined />
                <div class="ant-upload-text">上传</div>
            </div>
        </a-upload>
        <a-modal :open="previewVisible" :footer="null" @cancel="handleCancel">
            <img alt="example" v-if="fileType === 'img'" style="width: 100%" :src="previewImage" />
            <video v-if="fileType === 'video'" :src="previewImage" controls autoplay loop muted></video>
        </a-modal>
    </div>
</template>

<script setup>
import { ref, watch, onMounted } from 'vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import { UploadOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { config } from '@/config'
import apis from '@/apis'

defineOptions({
    name: 'GxUpload',
})
const fileType = ref('img')
const previewVisible = ref(false)
const previewImage = ref('')
const props = defineProps({
    modelValue: { type: Array, default: () => [] },
    headers: { type: Object, default: () => ({}) },
    multiple: { type: Boolean, default: false },
    maxSize: { type: Number, default: 10 }, // MB
    acceptTypes: { type: String, default: '*' },
    listType: { type: String, default: 'text' },
    disabled: { type: Boolean, default: false },
    uploadText: { type: String },
    fileNumber: { type: Number, default: 6 },
    width: {
        type: Number,
        default: 120,
    },
    height: {
        type: Number,
        default: 120,
    },
});

const emit = defineEmits(['update:modelValue', 'uploadSuccess', 'uploadError']);
const uploadUrl = config('http.apiBasic') + '/api/v1/upload'
const fileList = ref([]);
// 初始化文件列表
onMounted(() => {
    console.log(' props.modelValue', props.modelValue)
    fileList.value = props.modelValue.map(url => ({
        uid: `preview-${Date.now()}-${Math.random()}`,
        name: url.substring(url.lastIndexOf('/') + 1),
        status: 'done',
        url: url
    }));
});
// 文件上传前校验
const beforeUpload = (file) => {
    // const isValidType = props.acceptTypes === '*' ||
    //     props.acceptTypes.split(',').some(type => file.name.endsWith(type.replace('*', '')));
    // const isValidSize = file.size / 1024 / 1024 < props.maxSize;

    // if (!isValidType) {
    //     message.error(`仅支持 ${props.acceptTypes} 格式文件`);
    //     return false;
    // }
    // if (!isValidSize) {
    //     message.error(`文件大小不能超过 ${props.maxSize}MB`);
    //     return false;
    // }
    return true;
};
const handleCancel = () => {
    previewVisible.value = false;
};
const getBase64 = (file) => {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
    });
}
const handlePreview = async (file) => {
    console.log(file.name)
    const list = ['.avi', '.mp4', '.mov', '.wmv', '.mkv', '.m4v']
    const fileSuffix = file.name.substring(file.name.lastIndexOf('.'))
    if (list.includes(fileSuffix)) {
        fileType.value = 'video'
    }
    if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj)
    }
    previewImage.value = file.url || file.preview;
    console.log(previewImage.value)
    previewVisible.value = true;
};


// 修改handleChange方法
const handleChange = ({ file, fileList: updatedList }) => {
    // 处理上传成功的情况
    if (file.status === 'done') {
        const response = file.response;
        if (response && response.url) {
            // 找到当前文件项并更新URL
            const targetFile = updatedList.find(f => f.uid === file.uid);
            if (targetFile) {
                targetFile.url = response.url;
                message.success(`${file.name} 上传成功`);
            }

            // 更新外部绑定值
            const urls = updatedList
                .filter(item => item.status === 'done')
                .map(item => item.url);
            emit('update:modelValue', urls);
        }
    } else if (file.status === 'removed') {
        // 更新外部绑定值
        const urls = updatedList
            .filter(item => item.status === 'done')
            .map(item => item.url);
        emit('update:modelValue', urls);
    } else if (file.status === 'error') {
        message.error(`${file.name} 上传失败`);
    }
};

// 修复自定义上传方法
const handleCustomRequest = async (options) => {
    console.log("==options",options)
    const { file, onProgress, onSuccess, onError } = options;

    try {
        const formData = new FormData();
        formData.append('file', file);

        const { data } = await apis.common.uploadFile(formData);
        const fullUrl = config('http.apiBasic') + data;

        // 正确构造文件对象
        onSuccess({
            uid: file.uid,
            name: file.name,
            status: 'done',
            url: fullUrl,
            response: { url: fullUrl }  // 确保response包含URL
        }, file);

        // 触发成功事件
        emit('uploadSuccess', data);
    } catch (err) {
        onError(err);
        message.error('上传失败');
        emit('uploadError', err);
    }
};
// 同步外部v-model变化
watch(() => props.modelValue, (newVal) => {
    // fileList.value=[...newVal]
    // 仅同步已完成的项目
    const doneFiles = fileList.value.filter(f => f.status === 'done');
    const doneUrls = doneFiles.map(f => f.url);
    // 避免循环更新
    if (JSON.stringify(newVal) !== JSON.stringify(doneUrls)) {
        fileList.value = [
            ...newVal.map(url => {
                return {
                    uid: `preview-${Date.now()}-${Math.random()}`,
                    name: url.substring(url.lastIndexOf('/') + 1),
                    status: 'done',
                    url: url
                }
            }),
            ...fileList.value.filter(f => f.status !== 'done')
        ];
    }
}, { deep: true });
</script>
<style>
/* you can make up upload button and sample style by using stylesheets */
.ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
}
</style>
