<template>
    <section aria-label="File Upload Modal"
        class="relative h-full flex flex-col bg-white dark:bg-slate-900/70 shadow-xl rounded-md"
        v-on:dragenter="dragEnterHandler" v-on:dragleave="dragLeaveHandler" v-on:dragover="dragOverHandler"
        v-on:drop="dropHandler">

        <!-- overlay -->
        <div id="overlay" ref="overlay"
            class="w-full h-full absolute top-0 left-0 pointer-events-none z-50 flex flex-col items-center justify-center rounded-md">
            <i>
                <svg class="fill-current w-12 h-12 mb-3 text-blue-700" xmlns="http://www.w3.org/2000/svg" width="24"
                    height="24" viewBox="0 0 24 24">
                    <path
                        d="M19.479 10.092c-.212-3.951-3.473-7.092-7.479-7.092-4.005 0-7.267 3.141-7.479 7.092-2.57.463-4.521 2.706-4.521 5.408 0 3.037 2.463 5.5 5.5 5.5h13c3.037 0 5.5-2.463 5.5-5.5 0-2.702-1.951-4.945-4.521-5.408zm-7.479-1.092l4 4h-3v4h-2v-4h-3l4-4z" />
                </svg>
            </i>
            <p class="text-lg text-blue-700">Drop files to upload</p>
        </div>

        <!-- Loading Spinner when processing big files -->
        <div v-if="isLoading" class="absolute inset-0 z-60 flex items-center justify-center bg-gray-500 bg-opacity-50">
            <svg class="animate-spin h-12 w-12 text-white" xmlns="http://www.w3.org/2000/svg" fill="none"
                viewBox="0 0 24 24">
                <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                <path class="opacity-75" fill="currentColor" d="M12 2a10 10 0 0110 10h-4a6 6 0 00-6-6V2z"></path>
            </svg>
        </div>

        <!-- scroll area -->
        <div class="h-full p-8 w-full h-full flex flex-col">
            <header class="flex items-center justify-center w-full">
                <label for="dropzone-file"
                    class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600">
                    <div class="flex flex-col items-center justify-center pt-5 pb-6">
                        <svg aria-hidden="true" class="w-10 h-10 mb-3 text-gray-400" fill="none" stroke="currentColor"
                            viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12">
                            </path>
                        </svg>
                        <p class="mb-2 text-sm text-gray-500 dark:text-gray-400">
                            <span class="font-semibold">Click to upload</span> or drag and drop
                        </p>
                    </div>
                    <input id="dropzone-file" type="file" class="hidden" @click="showSpinner" @change="onChangeFile" @cancel="cancelSpinner" multiple="true" />
                </label>
            </header>

            <h1 class="pt-8 pb-3 font-semibold sm:text-lg text-gray-900">To Upload</h1>

            <draggable id="galleryxy" tag="ul" class="flex flex-1 flex-wrap -m-1" v-model="items" item-key="sort_order">
                <!-- <li
                    v-if="files.length == 0"
                    id="empty"
                    class="h-full w-full text-center flex flex-col items-center justify-center items-center"
                >
                    <svg
                        class="w-20 h-20 mb-3 text-gray-400"
                        version="1.1"
                        id="Capa_1"
                        xmlns="http://www.w3.org/2000/svg"
                        xmlns:xlink="http://www.w3.org/1999/xlink"
                        viewBox="0 0 412.533 412.533"
                        xml:space="preserve"
                        fill="#000000"
                    >
                        <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
                        <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
                        <g id="SVGRepo_iconCarrier">
                            <g>
                                <path
                                    style="fill: #010002"
                                    d="M412.485,203.954h0.041c0-14.323-5.609-27.336-14.729-37.042l0.016-0.016l-79.27-101.819H90.479 L13.493,168.961l0.033,0.033c-7.283,8.616-11.762,19.565-12.534,31.514C0.415,201.629,0,202.84,0,204.19v135.138 c0,4.495,3.642,8.129,8.129,8.129h396.276c4.495,0,8.129-3.633,8.129-8.129V204.19 C412.533,204.109,412.485,204.035,412.485,203.954z M97.844,81.335H311.43l48.389,68.5c-0.512-0.016-1-0.081-1.52-0.081h-97.502 v24.369c0,27.67-29.052,21.687-37.96,21.687h-32.466c-8.909,0-37.96,5.983-37.96-21.687v-24.369H54.9 c-1.016,0-2.008,0.098-3.016,0.146L97.844,81.335z M396.276,331.199H16.265V204.19c0-0.081-0.041-0.154-0.049-0.236h0.723 c0-20.923,17.029-37.944,37.96-37.944h81.253v8.112c0,27.987,21.281,37.944,54.218,37.944h32.466 c32.945,0,54.218-9.957,54.218-37.944v-8.112h81.261c10.461,0,19.948,4.251,26.824,11.12l0.016,0.016 c6.869,6.869,11.112,16.347,11.112,26.808h0.057c0,0.081-0.049,0.154-0.049,0.236C396.276,204.19,396.276,331.199,396.276,331.199z "
                                ></path>
                            </g>
                        </g>
                    </svg>
                    <span class="text-small text-gray-500">No files selected</span>
                </li> -->
                <template #item="{ index, element }">
                    <li class="block p-1 w-1/2 sm:w-1/3 md:w-1/4 lg:w-1/6 xl:w-1/8 h-24" :key="index">
                        <!-- :src="element.fileSrc" :src="generateURL(element)" -->
                        <!-- <article
                            v-if="element.type.match('image.*')"
                            tabindex="0"
                            class="bg-gray-50 group hasImage w-full h-full rounded-md cursor-pointer relative text-transparent hover:text-white shadow-sm"
                        >
                           
                            <img
                                :alt="element.name"
                                :src="element.fileSrc"
                                class="img-preview w-full h-full sticky object-cover rounded-md bg-fixed opacity-75"
                            />                            
                            <section class="flex flex-col rounded-md text-xs break-words w-full h-full z-20 absolute top-0 py-2 px-3">
                                <h1 class="flex-1">{{ element.name }}</h1>
                                <div class="flex">
                                    <p class="p-1 size text-xs">{{ getFileSize(element) }}</p>
                                    <p class="p-1 size text-xs text-gray-700">{{ element.sort_order }}</p>
                                    <button
                                        class="delete ml-auto focus:outline-none hover:bg-gray-300 p-1 rounded-md"
                                        @click.prevent="removeFile(index)"
                                    >
                                        <DeleteIcon></DeleteIcon>
                                    </button>
                                </div>
                            </section>                         
                        </article> -->
                        <!-- :class="errors && errors[`files.${index}`] ? 'bg-red-400' : 'bg-gray-100'" -->
                        <article tabindex="0"
                            class="bg-gray-100 group w-full h-full rounded-md cursor-pointer relative shadow-sm">
                            <section
                                class="flex flex-col rounded-md text-xs break-words w-full h-full z-20 absolute top-0 py-2 px-3">
                                <h1 class="flex-1 text-gray-700 group-hover:text-blue-800">{{ element.name }}</h1>
                                <div class="flex">
                                    <p class="p-1 size text-xs text-gray-700">{{ getFileSize(element) }}</p>
                                    <p class="p-1 size text-xs text-gray-700">sort: {{ element.sort_order }}</p>
                                    <button
                                        class="delete ml-auto focus:outline-none hover:bg-gray-300 p-1 rounded-md text-gray-800"
                                        @click.prevent="removeFile(index)">
                                        <DeleteIcon></DeleteIcon>
                                    </button>
                                </div>
                            </section>
                        </article>
                    </li>
                </template>
            </draggable>
            <!-- </ul> -->

            <!--<ul id="deletetFiles"></ul> -->

            <div>
                <h1 v-if="deletetFiles.length > 0" class="pt-8 pb-3 font-semibold sm:text-lg text-gray-900">Files To
                    Delete</h1>
                <ul id="deletetFiles" tag="ul" class="flex flex-1 flex-wrap -m-1">
                    <li v-for="(element, index) in deletetFiles" :key="index"
                        class="block p-1 w-1/2 sm:w-1/3 md:w-1/4 lg:w-1/6 xl:w-1/8 h-24">
                        <!-- <article
                            v-if="element.type.match('image.*')"
                            tabindex="0"
                            class="bg-red-50 group hasImage w-full h-full rounded-md cursor-pointer relative text-transparent hover:text-white shadow-sm"
                        >
                            <img
                                :alt="element.name"
                                :src="element.fileSrc"
                                class="img-preview w-full h-full sticky object-cover rounded-md bg-fixed opacity-75"
                            />
                            <section class="flex flex-col rounded-md text-xs break-words w-full h-full z-20 absolute top-0 py-2 px-3">
                                <h1 class="flex-1">{{ element.name }}</h1>
                                <div class="flex">
                                    <p class="p-1 size text-xs">{{ getFileSize(element) }}</p>
                                    <p class="p-1 size text-xs text-gray-700">{{ element.sort_order }}</p>
                                    <button
                                        class="delete ml-auto focus:outline-none hover:bg-gray-300 p-1 rounded-md"
                                        @click.prevent="reactivateFile(index)"
                                    >
                                        <RefreshIcon></RefreshIcon>
                                    </button>
                                </div>
                            </section>
                        </article> -->
                        <article tabindex="0"
                            class="bg-red-100 group w-full h-full rounded-md cursor-pointer relative shadow-sm">
                            <section
                                class="flex flex-col rounded-md text-xs break-words w-full h-full z-20 absolute top-0 py-2 px-3">
                                <h1 class="flex-1 text-gray-700 group-hover:text-blue-800">{{ element.name }}</h1>
                                <div class="flex">
                                    <!-- <p class="p-1 size text-xs text-gray-700">{{ getFileSize(element) }}</p> -->
                                    <p class="p-1 size text-xs text-gray-700">{{ element.sort_order }}</p>
                                    <button
                                        class="delete ml-auto focus:outline-none hover:bg-gray-300 p-1 rounded-md text-gray-800"
                                        @click.prevent="reactivateFile(index)">
                                        <RefreshIcon></RefreshIcon>
                                    </button>
                                </div>
                            </section>
                        </article>
                    </li>
                </ul>
            </div>

            <div v-if="fileErrors" class="flex flex-col mt-6 animate-fade-in" v-for="fileError in fileErrors">
                <div class="bg-yellow-500 border-l-4 border-orange-400 text-white p-4" role="alert">
                    <p class="font-bold">Be Warned</p>
                    <p>{{ fileError.join(', ') }}</p>
                </div>
            </div>

        </div>

        <!-- sticky footer -->
        <footer class="flex justify-end px-8 pb-8 pt-4">
            <button id="cancel"
                class="ml-3 rounded-sm px-3 py-1 hover:bg-gray-300 focus:shadow-outline focus:outline-none"
                @click="clearAllFiles">
                Clear
            </button>
        </footer>
    </section>
</template>

<script lang="ts">
import { Component, Vue, Prop, Ref, Watch } from 'vue-facing-decorator';
import { usePage } from '@inertiajs/vue3';
import DeleteIcon from '@/Components/Icons/Delete.vue';
import RefreshIcon from '@/Components/Icons/Refresh.vue';
// import { Page, PageProps, Errors, ErrorBag } from '@inertiajs/inertia';
import Draggable from 'vuedraggable';
// import { Buffer } from 'buffer';
import { TethysFile } from '@/Dataset';

// lastModified: 1691759507591
// lastModifiedDate: Fri Aug 11 2023 15:11:47 GMT+0200 (Mitteleuropäische Sommerzeit)
// name: 'freieIP.png'
// size: 112237
// type: 'image/png'
// webkitRelativePath: ''

interface IDictionary {
    [index: string]: Array<string>;
}
export declare type ErrorBag1 = Record<string, Array<string>>;
interface InteriaPage {
    // extends Page<PageProps> {
    [key: string]: boolean | number | string | Object | (string | null);
    errors: IDictionary;
    props: {
        // [key: string]: Array<string>;
        errors: IDictionary;
        auth: {
            user: {
                name: string;
            };
        };
        // laravelVersion: string;
        // phpVersion: string;
    };
}

@Component({
    name: 'file-upload',
    components: {
        DeleteIcon,
        RefreshIcon,
        Draggable,
    },
})
class FileUploadComponent extends Vue {

    @Ref('overlay') overlay: HTMLDivElement;


    public isLoading: boolean = false;
    private counter: number = 0;
    // @Prop() files: Array<TestFile>;

    @Prop({
        type: Array<File>,
        default: [],
    })
    files: Array<TethysFile | File>;


    @Prop({
        type: Array<File>,
        default: [],
    })
    filesToDelete: Array<TethysFile>;

    // // deletetFiles: Array<TethysFile> = [];
    get deletetFiles(): Array<TethysFile> {
        return this.filesToDelete;
    }
    set deletetFiles(values: Array<TethysFile>) {
        // this.modelValue = value;
        this.filesToDelete.length = 0;
        this.filesToDelete.push(...values);
    }

    get items(): Array<TethysFile | File> {
        return this.files;
    }
    set items(values: Array<TethysFile | File>) {
        // this.modelValue = value;
        this.files.length = 0;
        this.files.push(...values);
        // values.forEach((item, index) => {
        //     item.sort_order = index + 1; // Assuming sort_order starts from 1
        //     this.files.push(item);
        // });
    }

    @Watch('files', {
        deep: true, //also in case of pushing
    })
    public propertyWatcherFiles(newItems: Array<TethysFile>) {
        // Update sort_order based on the new index when the list is changed
        newItems.forEach((item, index) => {
            item.sort_order = index + 1; // Assuming sort_order starts from 1
        });
    }

    @Watch('filesToDelete', {
        deep: true, //also in case of pushing
    })
    public propertyWatcherDeletedFiles(newItems: Array<TethysFile>) {
        // Update sort_order based on the new index when the list is changed
        newItems.forEach((item, index) => {
            item.sort_order = index + 1; // Assuming sort_order starts from 1
        });
    }

    public created() {
        for (const file of this.files) {
            if (!(file instanceof File)) {
                // console.log(`${file.name} path is ${file.filePath} here.`);
                this.generateURL(file);
                // console.log(`${file.fileSrc} path.`);
            }
        }
    }

    public dragEnterHandler(e) {
        e.preventDefault();
        if (!this._hasFiles(e.dataTransfer)) {
            return;
        }
        ++this.counter && this.overlay.classList.add('draggedover');
    }

    public dragLeaveHandler() {
        1 > --this.counter && this.overlay.classList.remove('draggedover');
    }

    public dragOverHandler(event: DragEvent): void {
        if (this._hasFiles(event.dataTransfer)) {
            event.preventDefault();
        }
    }

    public startDrag(event: DragEvent, item: { id: string }) {
        const dataTransfer = event.dataTransfer;

        // Check if dataTransfer is not null
        if (dataTransfer) {
            dataTransfer.dropEffect = 'move';
            dataTransfer.effectAllowed = 'move';
            dataTransfer.setData('itemID', item.id);
        } else {
            console.warn('dataTransfer is null, drag event may not be supported.');
        }
    }

    // reset counter and append file to gallery when file is dropped
    public dropHandler(event: DragEvent): void {
        event.preventDefault();
        const dataTransfer = event.dataTransfer;
        // let bigFileFound = false;
        if (dataTransfer) {
            for (const file of event.dataTransfer?.files) {
                // let fileName = String(file.name.replace(/\.[^/.]+$/, ''));
                // file.label = fileName;
                // if (file.type.match('image.*')) {
                //     this.generateURL(file);
                // }
                // if (file.size > 62914560) { // 60 MB in bytes
                //     bigFileFound = true;
                // }
                this._addFile(file);
            }
            this.overlay.classList.remove('draggedover');
            this.counter = 0;
        }
        // if (bigFileFound) {
        //     this.isLoading = true;
        //     // Assume file processing delay; adjust timeout as needed or rely on async processing completion.
        //     setTimeout(() => {
        //         this.isLoading = false;
        //     }, 1500);
        // }
    }

    public showSpinner() {
        // event.preventDefault();
        this.isLoading = true;
    }

    public cancelSpinner() {
        // const target = event.target as HTMLInputElement;
        // // If no files were selected, remove spinner
        // if (!target.files || target.files.length === 0) {
        //     this.isLoading = false;
        // }
        this.isLoading = false;
    }

    public onChangeFile(event: Event) {
        event.preventDefault();
        let target = event.target as HTMLInputElement;
        // let uploadedFile = event.target.files[0];
        // let fileName = String(event.target.files[0].name.replace(/\.[^/.]+$/, ''));

        if (target && target.files) {
            for (const file of event.target.files) {
                // let fileName = String(event.target.files[0].name.replace(/\.[^/.]+$/, ''));
                // file.label = fileName;
                // if (file.type.match('image.*')) {
                //     this.generateURL(file);
                // }
                // Immediately set spinner if any file is large (over 100 MB)
                // for (const file of target.files) {
                //     if (file.size > 62914560) { // 100 MB
                //         bigFileFound = true;
                //         break;
                //     }
                // }
                // if (bigFileFound) {
                //     this.isLoading = true;
                // }
                this._addFile(file);

            }
        }
        // if (bigFileFound) {
        //     this.isLoading = true;
        //     setTimeout(() => {
        //         this.isLoading = false;
        //     }, 1500);
        // }
        // this.overlay.classList.remove('draggedover');
        this.counter = 0;
        this.isLoading = false;
    }

    get errors(): IDictionary {
        if (usePage().props.errors) {
            // return usePage().props.errors;
            return usePage<InteriaPage>().props.errors;
        } else {
            return {};
        }
    }

    get hasErrors(): boolean {
        return Object.keys(this.errors).length > 0;
    }

    get fileErrors() {
        return Object.fromEntries(Object.entries(this.errors).filter(([key]) => key.startsWith('file')));
    }

    public clearAllFiles(event: Event) {
        event.preventDefault();
        this.items.splice(0);
    }

    public removeFile(key: number) {
        // Check if the key is within the bounds of the items array
        if (key < 0 || key >= this.items.length) {
            console.error('Invalid key provided for removal.');
            return;
        }
        let fileToDelete = this.items[key];
        // Remove the file from items
        this.items.splice(key, 1);

        // Check if the file is of type TethysFile based on its properties
        if (this.isTethysFile(fileToDelete)) {
            this.deletetFiles.push(fileToDelete);
        }
    }
    // Helper method to check if a file is of type TethysFile
    private isTethysFile(file: any): file is TethysFile {
        // Replace the following conditions with the actual properties of TethysFile
        return file && typeof file.id === 'number'; // Example property check
    }

    public reactivateFile(key: number) {
        // Check if the key is within the bounds of the items array
        if (key < 0 || key >= this.deletetFiles.length) {
            console.error('Invalid key provided for reactivate.');
            return;
        }
        let fileToReactivate = this.deletetFiles[key];
        // Remove the file from items
        this.deletetFiles.splice(key, 1);

        // Check if the file is of type TethysFile based on its properties
        if (this.isTethysFile(fileToReactivate)) {
            this.items.push(fileToReactivate);
        }
    }

    public generateURL(file: TethysFile | File): string {
        // const arrayBuffer = Buffer.from(file.fileData.data);
        // const blob = new Blob([file.fileData.data], { type: 'application/octet-stream' });
        // const blob = new Blob([file.fileData], { type: 'image/png'});
        // let fileSrc = file.fileData;

        let localUrl: string = '';
        if (file instanceof File) {
            localUrl = URL.createObjectURL(file as Blob);
        }
        // else if (file.fileData) {
        //     // const blob = new Blob([file.fileData]);
        //     // localUrl = URL.createObjectURL(blob);
        //     const parsed = JSON.parse(file.fileData);
        //     file.fileData = '';
        //     // retrieve the original buffer of data
        //     const buff = Buffer.from(parsed.blob, 'base64');
        //     const blob = new Blob([buff], { type: 'application/octet-stream' });
        //     // file.blob = blob;
        //     localUrl = URL.createObjectURL(blob);
        //     file.fileSrc = localUrl;
        // }

        // setTimeout(() => {
        //     URL.revokeObjectURL(localUrl);
        // }, 1000);
        return localUrl;
    }

    public getFileSize(file: File) {
        if (file.size > 1024) {
            if (file.size > 1048576) {
                return Math.round(file.size / 1048576) + 'mb';
            } else {
                return Math.round(file.size / 1024) + 'kb';
            }
        } else {
            return file.size + 'b';
        }
    }

    private _addFile(file: File) {
        // const reader = new FileReader();
        // reader.onload = (event) => {
        //     const base64Data = (event.target as FileReader).result as string;
        //     this.items.push(test);

        // };
        // reader.readAsDataURL(file);
        if (file instanceof File) {
            // const base64Data = await this.readBase64(file);
            let test: TethysFile = {
                label: file.name,
                name: file.name,
                size: file.size,
                file_size: file.size,
                // fileData: JSON.stringify({ blob: base64Data }),
                // filePath: file.mozFullPath,
                // path_name:  file.mozFullPath,
                webkitRelativePath: '',
                lastModified: file.lastModified,
                type: file.type,
                mime_type: file.type,
                visible_in_frontdoor: false,
                visible_in_oai: false,
                fileSrc: file.type.match('image.*') ? this.generateURL(file) : '',
                blob: file as Blob,
                sort_order: this.items.length + 1,
            };
            // this.items.push(test);
            this.items[this.items.length] = test;
        } else {
            file.sort_order = this.items.length + 1;
            this.items.push(file);
        }
    }

    private _hasFiles(dataTransfer: DataTransfer | null): boolean {
        return dataTransfer ? dataTransfer.items.length > 0 : false;
    }
}
export default FileUploadComponent;
</script>

<style lang="css">
.hasImage:hover section {
    background-color: rgba(5, 5, 5, 0.4);
}

.hasImage:hover button:hover {
    background: rgba(5, 5, 5, 0.45);
}

section.hasError {
    background-color: rgba(5, 5, 5, 0.4);
}

#overlay p,
i {
    opacity: 0;
}

#overlay.draggedover {
    background-color: rgba(255, 255, 255, 0.7);
}

#overlay.draggedover p,
#overlay.draggedover i {
    opacity: 1;
}

.group:hover .group-hover\:text-blue-800 {
    color: #2b6cb0;
}
</style>
