<template>
    <section>
        <el-upload
            list-type="picture-card"
            accept="image/*"
            :action="uploadUrl"
            :on-preview="handlePictureCardPreview"
            :on-success="handleSuccess"
            :on-remove="handleRemove"
            v-model:file-list="fileList"
            @before-upload="beforeUpload"
            multiple
        >
            <el-icon>
                <Plus />
            </el-icon>
            <template #tip>
                <div class="el-upload__tip">
                    <slot></slot>
                </div>
            </template>
        </el-upload>
        <ElImageViewer v-if="showPreview" :url-list="[previewUrl]" teleported @close="showPreview = false" />
    </section>
</template>
<script setup>
import resolveUrl from 'resolve-url'
import { ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus } from '@vicons/tabler'
import { useImageSize } from '@/utils/imageSize'

const props = defineProps({
    modelValue: Array,
    maxWidth: {
        type: Number,
        default: -1
    },
    maxHeight: {
        type: Number,
        default: -1
    },
    maxSize: {
        type: Number,
        default: 1024 * 1024
    }
})
const emit = defineEmits(['update:modelValue'])
const uploadUrl = resolveUrl(import.meta.env.VITE_API_BASE_URL, '/api/file/upload')
const fileList = ref([])
const loading = ref(false)
const showPreview = ref(false)
const previewUrl = ref(null)
watch(
    () => props.modelValue,
    (val) => {
        if (val && val.join() === fileList.value.map((i) => i.realUrl).join()) {
            return
        }
        updateFileList(val)
    }
)
updateFileList(props.modelValue || [])
function updateFileList(list) {
    fileList.value = list.map((i) => {
        return {
            url: i,
            realUrl: i
        }
    })
}

async function beforeUpload(file) {
    if (!/^image/.test(file.type)) {
        this.$message.error('只能上传图片格式!')
        return false
    }
    if (this.maxSize > 0 && file.size > this.maxSize) {
        this.$message.error('上传图片大小不能超过 ' + this.maxSize / 1024 + 'KB!')
        return false
    }
    const { width, height } = await useImageSize(URL.createObjectURL(file))
    if (props.maxWidth > 0 && width > props.maxWidth) {
        this.$message.error('上传图片宽度不能超过 ' + props.maxWidth + 'px!')
        return false
    } else if (props.maxHeight > 0 && height > props.maxHeight) {
        this.$message.error('上传图片高度不能超过 ' + props.maxHeight + 'px!')
        return false
    } else {
        loading.value = true
        return true
    }
}
function handlePictureCardPreview(file) {
    previewUrl.value = file.url || file.realUrl
    showPreview.value = true
}
function handleSuccess(res, file, fileList) {
    file.realUrl = res.url
    emit(
        'update:modelValue',
        fileList.map((i) => i.realUrl)
    )
}
function handleRemove(file, fileList) {
    emit(
        'update:modelValue',
        fileList.map((i) => i.realUrl)
    )
}
</script>
<style lang="less" scoped></style>
