<template>
    <el-upload
        v-model:file-list="fileList"
        class="single-upload"
        :action="uploadUrl"
        :show-file-list="false"
        :on-success="onSuccess"
        :before-upload="beforeUpload"
        accept="image/*"
        @on-change="onChange"
    >
        <template #trigger>
            <div
                class="w-40 h-40 bg-neutral-100 dark:bg-neutral-900 rounded-md cursor-pointer border border-dashed border-gray-500 hover:border-blue-500 flex justify-center items-center overflow-hidden relative"
                v-loading="loading"
            >
                <img v-if="imageUrl" :src="imageUrl" class="w-full h-full object-cover" />
                <Plus v-if="!imageUrl && !loading" class="w-10 h-10 text-gray-400"> </Plus>
                <div v-if="imageUrl" class="absolute bottom-4 left-0 right-0 flex items-center justify-center">
                    <Eye
                        class="w-5 h-5 text-neutral-100 drop-shadow-md cursor-pointer"
                        @click.stop="showPreview = true"
                    />
                    <Trash class="w-5 h-5 text-neutral-100 drop-shadow-md cursor-pointer ml-4" @click.stop="clear" />
                </div>
            </div>
        </template>
        <template #tip>
            <div class="el-upload__tip">
                <slot></slot>
            </div>
        </template>
    </el-upload>
    <ElImageViewer v-if="showPreview" :url-list="[imageUrl]" teleported @close="showPreview = false" />
</template>
<script setup>
import { ref, unref, watch } from 'vue'
import resolveUrl from 'resolve-url'
import { Plus, Upload, Trash, Eye } from '@vicons/tabler'
import { useImageSize } from '@/utils/imageSize'
const props = defineProps({
    modelValue: String,
    usePrefix: {
        type: Boolean,
        default: true
    },
    url: {
        type: String
    },
    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 loading = ref(false)
const fileList = ref([])
const imageUrl = ref(null)
const showPreview = ref(false)

if (props.modelValue) {
    imageUrl.value = unref(props.modelValue)
    fileList.value = [
        {
            url: unref(props.modelValue)
        }
    ]
}
watch(
    () => props.modelValue,
    (val) => {
        imageUrl.value = val
        fileList.value = [
            {
                url: val
            }
        ]
    }
)
function onSuccess(res, file) {
    loading.value = false
    imageUrl.value = URL.createObjectURL(file.raw)
    emit('update:modelValue', res.url)
}
function onError(err, file, fileList) {
    loading.value = false
}
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 onChange(e) {
    console.log(e)
}
function clear() {
    emit('update:modelValue', null)
}
</script>
<style lang="less" scoped>
.single-uploader-icon {
    color: var(--el-text-color-secondary);
    border: 1px dashed var(--el-border-color);
    border-radius: var(--el-border-radius-base);
    background-color: var(--el-bg-color);
}

.upload-image {
    height: 178px;
    display: block;
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;

    &:hover {
        border-color: #409eff;
    }
}

.wrapper {
    position: relative;
    font-size: 12px;
}

.single-upload .el-upload {
    position: relative;
}

.loading {
    position: absolute;
    top: 1px;
    bottom: 1px;
    left: 1px;
    right: 1px;
    margin: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.6);
    color: #333;
    font-size: 24px;
    border-radius: 7px;
    overflow: hidden;
}
</style>
