import {createIcons, icons} from "lucide";
export const CHUNK_SIZE = 8192;
export function FSUploader(){
    return {
        files: [],
        rawFiles: [],
        section: document.querySelector("meta[name='fs-section']")?.content ?? '',
        init( oldFiles ){
            this.$watch('files', () =>{
                this.$nextTick(() => window.refreshIcons(this.$el) )
            })
        },
        get isUploading(){
            return this.files.some(f => !f.done && !f.error);
        },
        get hasErrors(){
          return this.files.some(f => f.error);
        },
        get allUploaded(){
          return this.files.length === 0 || this.files.every(f => f.done);
        },
        async submitFile(e){
            const selected = Array.from(e.target.files);
            e.target.value = '';

            for( const raw of selected ){
                const totalChunks = Math.ceil(raw.size / CHUNK_SIZE );
                const index = this.files.length;
                this.files.push({
                    name: raw.name,
                    progress: 0,
                    currentChunk: 0,
                    totalChunks: totalChunks,
                    done: false,
                    error: null,
                    uuid: crypto.randomUUID()
                });
                this.rawFiles.push(raw);
                this.uploadChunks(raw,index);
            }
        },
        async uploadChunks(rawFile, index){
            const file = this.files[index];
            const url = `/api/fs/upload-chunk/${this.section}`;
            const csrf = document.querySelector('meta[name=csrf-token]')?.content ?? '';

            for( let i = 0; i < file.totalChunks; i++ ){
                if( file.error )
                    return;

                const start = i * CHUNK_SIZE;
                const end = Math.min(start + CHUNK_SIZE, rawFile.size);
                const chunk = rawFile.slice(start, end);
                const formData = new FormData();

                formData.append('file', chunk);
                formData.append('file_uuid', file.uuid);
                formData.append('current_chunk', i);
                formData.append('total_chunks', file.totalChunks);
                formData.append( 'filename', rawFile.name );
                formData.append('_token', csrf );

                try {
                    const response = await fetch(url, { method: 'POST', body: formData });
                    if(!response.ok)
                        throw new Error(`${response.status} ${response.statusText}`);

                    const data = await response.json();
                    if( data.success !== true || data.uploaded !== true )
                        throw new Error(`${data.error}`);

                    file.currentChunk = i + 1;
                    file.progress = Math.round((( i + 1) / file.totalChunks ) * 100);

                    if( data.finished === true ){
                        file.done = true;
                    }
                } catch(err){
                    file.error = 'Error on chunk ' + ( i + 1 ) + '. ' + err.message;
                    file.progress = 0;
                    return;
                }
            }
        },
        retry(index){
            const rawFile = this.rawFiles[index];
            const totalChunks = Math.ceil(rawFile.size / CHUNK_SIZE );
            this.files[index] = {
                name: rawFile.name,
                progress: 0,
                currentChunk: 0,
                totalChunks: totalChunks,
                done: false,
                error: null,
                uuid: crypto.randomUUID()
            };
            this.uploadChunks(raw,index);
        },
        remove(index){
            this.files.splice(index, 1);
            this.rawFiles.splice(index, 1);
        }
    }
}
