<template>
    <div>
        <input
            :id="id"
            type="file"
            :name="name + (multiple ? '[]' : '')"
            :multiple="multiple"
            :disabled="uploading"
            :accept="mime"
            @change="filesChange($event.target.name, $event.target.files)"
        >
        <label
            :for="id"
            :class="['uploader-container', form ? 'form-control p-2' : classes, drag ? 'drag' : '']"
            @dragover="drag = true"
            @dragleave="drag = false"
        >
            <p v-if="errorMessage" class="text-danger mb-0">
                <Icon v="exclamation-circle" />
                <T>{{ errorMessage }}</T>
            </p>
            <p v-else-if="uploading" class="mb-0">
                <Spinner />
            </p>
            <p v-else class="mb-0">
                <slot>
                    <Icon v="upload" />
                    <T>images.upload.instructionShort</T>
                </slot>
            </p>
        </label>
    </div>
</template>

<script>
export default {
    props: {
        url: { required: true },
        multiple: { type: Boolean },
        mime: { default: '*/*' },
        name: { default: 'files' },
        form: { type: Boolean },
        classes: { default: 'btn btn-outline-primary btn-sm' },
    },
    emits: ['uploaded'],
    data() {
        return {
            uploading: false,
            drag: false,
            errorMessage: '',
            id: `upload-${this.name}`,
        };
    },
    methods: {
        async filesChange(fieldName, fileList) {
            if (!fileList.length) {
                return;
            }
            this.drag = false;
            const formData = new FormData();
            for (const file of fileList) {
                formData.append(fieldName, file, file.name);
            }
            await this.save(formData);
        },
        async save(formData) {
            this.uploading = true;
            this.errorMessage = '';
            try {
                const ids = await $fetch(this.url, {
                    method: 'POST',
                    body: formData,
                });
                this.$emit('uploaded', ids);
            } catch (e) {
                this.errorMessage = e?.response?.data?.error || 'error.invalidImage';
            }
            this.uploading = false;
        },
    },
};
</script>

<style lang="scss" scoped>
    @use "sass:color";
    @import "assets/variables";

    .uploader-container {
        position: relative;
        cursor: pointer;
        &.form-control {
            &:hover, &.drag {
                background: color.adjust($primary, $lightness: 50%, $space: hsl);
            }
        }
    }

    input[type="file"] {
        display: none;
    }
</style>
