/**
 * EasyStream Upload Progress Widget
 *
 * Displays real-time upload progress for files being uploaded
 * Features:
 * - Multiple simultaneous uploads
 * - Real-time progress bars
 * - Processing status indicators
 * - Cancel uploads
 * - Auto-hide when complete
 */

class UploadProgressWidget {
    constructor(options = {}) {
        this.options = {
            apiUrl: options.apiUrl || '/api/upload/progress.php',
            pollInterval: options.pollInterval || 1000, // Poll every second
            autoHide: options.autoHide !== false,
            hideDelay: options.hideDelay || 3000,
            ...options
        };

        this.uploads = new Map();
        this.widget = null;
        this.pollTimer = null;

        this.init();
    }

    init() {
        this.createWidget();
        this.loadExistingUploads();
    }

    createWidget() {
        const widget = document.createElement('div');
        widget.className = 'upload-progress-widget';
        widget.innerHTML = `
            <div class="upload-widget-header">
                <h3>Uploads</h3>
                <button class="collapse-btn" aria-label="Collapse">−</button>
            </div>
            <div class="upload-widget-body">
                <div class="upload-list"></div>
            </div>
        `;

        document.body.appendChild(widget);
        this.widget = widget;

        // Collapse functionality
        widget.querySelector('.collapse-btn').addEventListener('click', () => {
            widget.classList.toggle('collapsed');
            widget.querySelector('.collapse-btn').textContent =
                widget.classList.contains('collapsed') ? '+' : '−';
        });

        this.injectStyles();
    }

    injectStyles() {
        const style = document.createElement('style');
        style.textContent = `
            .upload-progress-widget {
                position: fixed;
                bottom: 20px;
                right: 20px;
                width: 380px;
                max-height: 500px;
                background: white;
                border-radius: 12px;
                box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
                z-index: 9999;
                display: none;
                flex-direction: column;
                overflow: hidden;
            }

            .upload-progress-widget.visible {
                display: flex;
            }

            .upload-progress-widget.collapsed .upload-widget-body {
                display: none;
            }

            .upload-widget-header {
                padding: 16px 20px;
                background: #f9f9f9;
                border-bottom: 1px solid #e0e0e0;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }

            .upload-widget-header h3 {
                margin: 0;
                font-size: 16px;
                font-weight: 600;
            }

            .collapse-btn {
                background: none;
                border: none;
                font-size: 20px;
                cursor: pointer;
                padding: 0;
                width: 24px;
                height: 24px;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            .upload-widget-body {
                overflow-y: auto;
                max-height: 440px;
            }

            .upload-list {
                padding: 12px;
            }

            .upload-item {
                padding: 12px;
                margin-bottom: 12px;
                background: #f9f9f9;
                border-radius: 8px;
                border: 1px solid #e0e0e0;
            }

            .upload-item.completed {
                background: #e8f5e9;
                border-color: #4caf50;
            }

            .upload-item.failed {
                background: #ffebee;
                border-color: #f44336;
            }

            .upload-header {
                display: flex;
                justify-content: space-between;
                align-items: flex-start;
                margin-bottom: 8px;
            }

            .upload-filename {
                font-weight: 500;
                font-size: 14px;
                flex: 1;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }

            .upload-cancel {
                background: none;
                border: none;
                color: #f44336;
                cursor: pointer;
                padding: 0 4px;
                font-size: 18px;
            }

            .upload-status {
                font-size: 12px;
                color: #666;
                margin-bottom: 8px;
            }

            .upload-progress-bar {
                height: 6px;
                background: #e0e0e0;
                border-radius: 3px;
                overflow: hidden;
                margin-bottom: 4px;
            }

            .upload-progress-fill {
                height: 100%;
                background: linear-gradient(90deg, #065fd4, #1e88e5);
                transition: width 0.3s ease;
                position: relative;
            }

            .upload-progress-fill.processing {
                background: linear-gradient(90deg, #f57c00, #ff9800);
                animation: pulse 1.5s ease-in-out infinite;
            }

            .upload-progress-fill.completed {
                background: #4caf50;
            }

            .upload-progress-fill.failed {
                background: #f44336;
            }

            @keyframes pulse {
                0%, 100% { opacity: 1; }
                50% { opacity: 0.7; }
            }

            .upload-percent {
                font-size: 12px;
                color: #666;
                text-align: right;
            }

            .upload-error {
                font-size: 12px;
                color: #f44336;
                margin-top: 4px;
            }

            @media (max-width: 480px) {
                .upload-progress-widget {
                    width: calc(100% - 40px);
                    right: 20px;
                    left: 20px;
                }
            }

            @media (prefers-color-scheme: dark) {
                .upload-progress-widget {
                    background: #212121;
                }

                .upload-widget-header {
                    background: #2a2a2a;
                    border-bottom-color: #303030;
                }

                .upload-item {
                    background: #2a2a2a;
                    border-color: #303030;
                }
            }
        `;

        document.head.appendChild(style);
    }

    addUpload(uploadId, filename, fileType) {
        this.uploads.set(uploadId, {
            id: uploadId,
            filename: filename,
            fileType: fileType,
            status: 'uploading',
            percent: 0
        });

        this.renderUpload(uploadId);
        this.show();
        this.startPolling();
    }

    renderUpload(uploadId) {
        const upload = this.uploads.get(uploadId);
        if (!upload) return;

        const list = this.widget.querySelector('.upload-list');
        let item = list.querySelector(`[data-upload-id="${uploadId}"]`);

        if (!item) {
            item = document.createElement('div');
            item.className = 'upload-item';
            item.dataset.uploadId = uploadId;
            list.appendChild(item);
        }

        const statusText = this.getStatusText(upload.status, upload.processingStep);
        const progressClass = upload.status === 'processing' || upload.status === 'encoding' ? 'processing' :
                              upload.status === 'completed' ? 'completed' :
                              upload.status === 'failed' ? 'failed' : '';

        item.className = `upload-item ${upload.status}`;
        item.innerHTML = `
            <div class="upload-header">
                <div class="upload-filename" title="${upload.filename}">${upload.filename}</div>
                ${upload.status === 'uploading' || upload.status === 'processing' ?
                    `<button class="upload-cancel" data-upload-id="${uploadId}" aria-label="Cancel">×</button>` :
                    ''}
            </div>
            <div class="upload-status">${statusText}</div>
            <div class="upload-progress-bar">
                <div class="upload-progress-fill ${progressClass}" style="width: ${upload.percent}%"></div>
            </div>
            <div class="upload-percent">${Math.round(upload.percent)}%</div>
            ${upload.errorMessage ? `<div class="upload-error">${upload.errorMessage}</div>` : ''}
        `;

        // Add cancel handler
        const cancelBtn = item.querySelector('.upload-cancel');
        if (cancelBtn) {
            cancelBtn.addEventListener('click', () => this.cancelUpload(uploadId));
        }
    }

    getStatusText(status, processingStep) {
        const statusMap = {
            'uploading': 'Uploading...',
            'processing': processingStep || 'Processing...',
            'encoding': processingStep || 'Encoding video...',
            'completed': 'Upload complete!',
            'failed': 'Upload failed',
            'cancelled': 'Cancelled'
        };

        return statusMap[status] || status;
    }

    async updateStatus(uploadId) {
        try {
            const response = await fetch(`${this.options.apiUrl}?action=get_status&upload_id=${uploadId}`);
            const data = await response.json();

            if (data.error) {
                console.error('Error fetching upload status:', data.error);
                return;
            }

            const upload = this.uploads.get(uploadId);
            if (upload) {
                upload.status = data.status;
                upload.percent = data.upload_percent;
                upload.processingStep = data.processing_step;
                upload.errorMessage = data.error_message;
                upload.fileKey = data.file_key;

                this.renderUpload(uploadId);

                // Auto-hide completed uploads
                if (data.status === 'completed' && this.options.autoHide) {
                    setTimeout(() => {
                        this.removeUpload(uploadId);
                    }, this.options.hideDelay);
                }

                // Stop polling if all uploads are done
                if (data.status === 'completed' || data.status === 'failed' || data.status === 'cancelled') {
                    const hasActive = Array.from(this.uploads.values()).some(u =>
                        u.status === 'uploading' || u.status === 'processing' || u.status === 'encoding'
                    );

                    if (!hasActive) {
                        this.stopPolling();
                    }
                }
            }
        } catch (error) {
            console.error('Error updating upload status:', error);
        }
    }

    async loadExistingUploads() {
        try {
            const response = await fetch(`${this.options.apiUrl}?action=get_all`);
            const data = await response.json();

            if (data.uploads && data.uploads.length > 0) {
                data.uploads.forEach(upload => {
                    this.uploads.set(upload.upload_id, {
                        id: upload.upload_id,
                        filename: upload.filename,
                        fileType: upload.file_type,
                        status: upload.status,
                        percent: upload.upload_percent,
                        processingStep: upload.processing_step
                    });

                    this.renderUpload(upload.upload_id);
                });

                this.show();
                this.startPolling();
            }
        } catch (error) {
            console.error('Error loading existing uploads:', error);
        }
    }

    async cancelUpload(uploadId) {
        try {
            const response = await fetch(`${this.options.apiUrl}?action=cancel&upload_id=${uploadId}`);
            const data = await response.json();

            if (data.success) {
                this.removeUpload(uploadId);
            }
        } catch (error) {
            console.error('Error cancelling upload:', error);
        }
    }

    removeUpload(uploadId) {
        this.uploads.delete(uploadId);
        const item = this.widget.querySelector(`[data-upload-id="${uploadId}"]`);
        if (item) {
            item.remove();
        }

        if (this.uploads.size === 0) {
            this.hide();
        }
    }

    startPolling() {
        if (this.pollTimer) return;

        this.pollTimer = setInterval(() => {
            this.uploads.forEach((upload, id) => {
                if (upload.status === 'uploading' || upload.status === 'processing' || upload.status === 'encoding') {
                    this.updateStatus(id);
                }
            });
        }, this.options.pollInterval);
    }

    stopPolling() {
        if (this.pollTimer) {
            clearInterval(this.pollTimer);
            this.pollTimer = null;
        }
    }

    show() {
        this.widget.classList.add('visible');
    }

    hide() {
        this.widget.classList.remove('visible');
        this.stopPolling();
    }
}

// Export for use in other scripts
window.UploadProgressWidget = UploadProgressWidget;
