import { NjetComponent, NjetDialog } from './njet.js';

const FUG_ICONS = {
    file: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><rect x="8" y="8" width="32" height="40" rx="5" fill="white" stroke="%234af" stroke-width="2"/></svg>'
};

class FileUploadGrid extends NjetComponent {
    constructor() {
        super();
        this._grid = null;
        this._fileInput = null;
    }

  openFileDialog() {
        if(this.isBusy){
            const dialog = new NjetDialog({
                title: 'Upload in progress',
                content: 'Please wait for the current upload to complete.',
                primaryButton: {
                    text: 'OK',
                    handler: function () {
                        this.closest('njet-dialog').remove();
                    }
                }
            })
            return false 
        }

        if (this._fileInput) {
            this._fileInput.value = ''; // Allow same file selection twice
            this._fileInput.click();
        }
      return true;
    }

    connectedCallback() {
        this.render();
        this._fileInput.addEventListener('change', e => this.handleFiles(e.target.files));
    }

    render() {
        // Root wrapper for styling
        this.classList.add('fug-root');
        // Clear previous (if rerendered)
        this.innerHTML = '';
        // Input
        this._fileInput = document.createElement('input');
        this._fileInput.type = 'file';
        this._fileInput.className = 'fug-fileinput';
        this._fileInput.multiple = true;
        // Grid
        this._grid = document.createElement('div');
        this._grid.className = 'fug-grid';
        this.appendChild(this._fileInput);
        this.appendChild(this._grid);
        this.uploadsDone = 0;
        this.uploadsStarted = 0;


    }

    reset(){
        this.uploadsDone = 0;
        this.uploadsStarted = 0;
        this._grid.innerHTML = '';
    }

    get isBusy(){
        return this.uploadsDone != this.uploadsStarted;
    }

    handleFiles(files) {
        this.reset()
        this.uploadsDone = 0;
        this.uploadsStarted = files.length;
        [...files].forEach(file => this.createTile(file));
    }

    createTile(file) {
        const tile = document.createElement('div');
        tile.className = 'fug-tile';
        // Icon/Thumbnail
        let icon;
        if (file.type.startsWith('image/')) {
            icon = document.createElement('img');
            icon.className = 'fug-icon';
            icon.src = URL.createObjectURL(file);
            icon.onload = () => URL.revokeObjectURL(icon.src);
        } else if (file.type.startsWith('video/')) {
            icon = document.createElement('video');
            icon.className = 'fug-icon';
            icon.src = URL.createObjectURL(file);
            icon.muted = true;
            icon.playsInline = true;
            icon.controls = false;
            icon.preload = 'metadata';
            icon.onloadeddata = () => {
                icon.currentTime = 0.5;
                URL.revokeObjectURL(icon.src);
            };
        } else {
            icon = document.createElement('img');
            icon.className = 'fug-icon';
            icon.src = FUG_ICONS.file;
        }
        // Filename
        const name = document.createElement('div');
        name.className = 'fug-filename';
        name.textContent = file.name;
        // Progressbar
        const progressbar = document.createElement('div');
        progressbar.className = 'fug-progressbar';
        const progress = document.createElement('div');
        progress.className = 'fug-progress';
        progressbar.appendChild(progress);

        // Tile composition
        tile.appendChild(icon);
        tile.appendChild(name);
        tile.appendChild(progressbar);
        this._grid.appendChild(tile);
        
        // Start upload
        this.startUpload(file, tile, progress);

    }

    startUpload(file, tile, progress) {

        this.publish('file-uploading', {file: file, tile: tile, progress: progress});

        const ws = new WebSocket(`ws://${location.host}/ws`);
        ws.binaryType = 'arraybuffer';
        let sent = 0;

        ws.onopen = async () => {
            ws.send(JSON.stringify({type: 'start', filename: file.name}));
            const chunkSize = 64*1024;
            while (sent < file.size) {
                const chunk = file.slice(sent, sent + chunkSize);
                ws.send(await chunk.arrayBuffer());
                sent += chunkSize;
            }
            ws.send(JSON.stringify({type: 'end', filename: file.name}));
        };

        ws.onmessage = (event) => {


            const data = JSON.parse(event.data);
            if (data.type === 'progress') {
                const pct = Math.min(100, Math.round(100 * data.bytes / file.size));
                progress.style.width = pct + '%';
                this.publish('file-uploading', {file: file, tile: tile, progress: progress});
            } else if (data.type === 'done') {
                
                this.uploadsDone += 1;
                this.publish('file-uploaded', {file: file, tile: tile, progress: progress});
                progress.style.width = '100%';
                tile.classList.add('fug-done');

                ws.close();

                this.reset()
            }
        };
    }
}

customElements.define('file-upload-grid', FileUploadGrid);

export { FileUploadGrid };
