<template>
    <div @dragenter.prevent="dragenter" @dragover.prevent="dragover" @dragleave.prevent="dragleave"
         @drop.prevent="drop" ref="dropzone">
        <slot></slot>
    </div>
</template>

<style scoped>
.dragover {
    opacity: 0.5;
}
</style>

<script>
import * as BIcons from "bootstrap-icons-vue";

export default {
    name: "DragDropFileSource",
    components: {
        ...BIcons
    },
    emits: ["input"],
    methods: {
        dragenter(e) {
            if (e.dataTransfer.types.includes("Files")) {
                e.preventDefault()
                e.stopPropagation()
                this.$refs.dropzone.classList.add("dragover")
            }else{
                console.log(e.dataTransfer.types) //TODO text/uri-list?
            }
        },
        dragover(e) {
            if (e.dataTransfer.types.includes("Files")) {
                e.preventDefault()
                e.stopPropagation()
                this.$refs.dropzone.classList.add("dragover")
            }
        },
        dragleave(e) {
            if (e.dataTransfer.types.includes("Files")) {
                e.preventDefault()
                e.stopPropagation()
                this.$refs.dropzone.classList.remove("dragover")
            }
        },
        drop(e) {
            if (e.dataTransfer.types.includes("Files")) {
                e.preventDefault()
                e.stopPropagation()
                this.$refs.dropzone.classList.remove("dragover")
                const jobs = [...e.dataTransfer.files].map((file) => {
                    return new Promise((resolve, reject) => {
                        let reader = new FileReader();
                        reader.readAsArrayBuffer(file)
                        reader.onloadend = async () => {
                            const buffer = reader.result;
                            if (!(buffer instanceof ArrayBuffer)) {
                                console.log(buffer)
                                reject("Not an ArrayBuffer");
                                return;
                            }
                            const data = new Uint8Array(buffer);
                            // SHA-256 must match the backend's content hash for file identification. See docs/implementation.md#sha-256-file-hashing-must-match-the-backend.
                            const hashBuffer = await crypto.subtle.digest('SHA-256', data);
                            const hash = Array.from(new Uint8Array(hashBuffer))
                                .map(b => b.toString(16).padStart(2, "0")).join("");
                            var base64 = btoa(
                                data.reduce((a, b) => a + String.fromCharCode(b), '')
                            );
                            resolve({
                                name: file.name,
                                size: file.size,
                                mime_type: file.type,
                                data: base64,
                                hash: hash,
                            });
                        }
                        reader.onerror = (e) => {
                            reject(e)
                        }
                    })
                })
                Promise.all(jobs).then((files) => {
                    this.$emit("input", files)
                    console.log("drop", files)
                })
            }
        }
    }
}
</script>