// Reusable Firmware Upload Component
class FirmwareUploadComponent extends Component {
    constructor(container, viewModel, eventBus) {
        super(container, viewModel, eventBus);
        
        logger.debug('FirmwareUploadComponent: Constructor called');
        logger.debug('FirmwareUploadComponent: Container:', container);
        logger.debug('FirmwareUploadComponent: Container ID:', container?.id);
        
        // Initialize overlay dialog
        this.overlayDialog = null;
    }

    setupEventListeners() {
        // Setup firmware file input
        const firmwareFile = this.findElement('#firmware-file');
        if (firmwareFile) {
            this.addEventListener(firmwareFile, 'change', this.handleFileSelect.bind(this));
        }

        // Setup deploy button
        const deployBtn = this.findElement('#deploy-btn');
        if (deployBtn) {
            this.addEventListener(deployBtn, 'click', this.handleDeploy.bind(this));
        }

        // Setup WebSocket listener for real-time firmware upload status
        this.setupWebSocketListeners();
    }

    setupViewModelListeners() {
        this.subscribeToProperty('selectedFile', () => {
            this.updateFileInfo();
            this.updateDeployButton();
        });
        this.subscribeToProperty('isUploading', this.updateUploadState.bind(this));
        this.subscribeToProperty('uploadProgress', this.updateUploadProgress.bind(this));
        this.subscribeToProperty('uploadResults', this.updateUploadResults.bind(this));
    }

    setupWebSocketListeners() {
        // Listen for real-time firmware upload status updates
        window.wsClient.on('firmwareUploadStatus', (data) => {
            this.handleFirmwareUploadStatus(data);
        });
    }

    handleFirmwareUploadStatus(data) {
        const { nodeIp, status, filename, fileSize, timestamp } = data;

        logger.debug('FirmwareUploadComponent: Firmware upload status received:', { nodeIp, status, filename });

        // Check if there's currently an upload in progress
        const isUploading = this.viewModel.get('isUploading');
        if (!isUploading) {
            logger.debug('FirmwareUploadComponent: No active upload, ignoring status update');
            return;
        }

        // Find the target node item for this node
        const targetNodeItem = this.findElement(`[data-node-ip="${nodeIp}"]`);
        if (!targetNodeItem) {
            logger.debug('FirmwareUploadComponent: No target node item found for node:', nodeIp);
            return;
        }

        // Update the status display based on the received status
        const statusElement = targetNodeItem.querySelector('.status-indicator');

        if (statusElement) {
            let displayStatus = status;
            let statusClass = '';

            logger.debug(`FirmwareUploadComponent: Updating status for node ${nodeIp}: ${status} -> ${displayStatus}`);

            switch (status) {
                case 'uploading':
                    displayStatus = 'Uploading...';
                    statusClass = 'uploading';
                    break;
                case 'completed':
                    displayStatus = 'Completed';
                    statusClass = 'success';
                    logger.debug(`FirmwareUploadComponent: Node ${nodeIp} marked as completed`);
                    break;
                case 'failed':
                    displayStatus = 'Failed';
                    statusClass = 'error';
                    break;
                default:
                    displayStatus = status;
                    break;
            }

            statusElement.textContent = displayStatus;
            statusElement.className = `status-indicator ${statusClass}`;
        }

        // Update overall progress if we have multiple nodes
        this.updateOverallProgressFromStatus();

        // Check if all uploads are complete and finalize results
        this.checkAndFinalizeUploadResults();
    }

    updateOverallProgressFromStatus() {
        const targetNodeItems = Array.from(this.findAllElements('.target-node-item'));
        if (targetNodeItems.length <= 1) {
            return; // Only update for multi-node uploads
        }

        let completedCount = 0;
        let failedCount = 0;
        let uploadingCount = 0;

        targetNodeItems.forEach(item => {
            const statusElement = item.querySelector('.status-indicator');
            if (statusElement) {
                const status = statusElement.textContent;
                if (status === 'Completed') {
                    completedCount++;
                } else if (status === 'Failed') {
                    failedCount++;
                } else if (status === 'Uploading...') {
                    uploadingCount++;
                }
            }
        });

        const totalNodes = targetNodeItems.length;
        const successfulUploads = completedCount;
        const successPercentage = Math.round((successfulUploads / totalNodes) * 100);

        // Update overall progress bar
        const progressBar = this.findElement('#overall-progress-bar');
        const progressText = this.findElement('.progress-text');

        if (progressBar && progressText) {
            progressBar.style.width = `${successPercentage}%`;

            // Update progress bar color based on completion
            if (successPercentage === 100) {
                progressBar.style.backgroundColor = '#4ade80';
            } else if (successPercentage > 50) {
                progressBar.style.backgroundColor = '#60a5fa';
            } else {
                progressBar.style.backgroundColor = '#fbbf24';
            }

            progressText.textContent = `${successfulUploads}/${totalNodes} Successful (${successPercentage}%)`;
        }

        // Update progress summary
        const progressSummary = this.findElement('#progress-summary');
        if (progressSummary) {
            if (failedCount > 0) {
                progressSummary.innerHTML = `<span>${window.icon('warning', { width: 14, height: 14 })} Upload in progress... (${uploadingCount} uploading, ${failedCount} failed)</span>`;
            } else if (uploadingCount > 0) {
                progressSummary.innerHTML = `<span>${window.icon('info', { width: 14, height: 14 })} Upload in progress... (${uploadingCount} uploading)</span>`;
            } else if (completedCount === totalNodes) {
                progressSummary.innerHTML = `<span>${window.icon('success', { width: 14, height: 14 })} All uploads completed successfully at ${new Date().toLocaleTimeString()}</span>`;
            }
        }
    }

    checkAndFinalizeUploadResults() {
        const targetNodeItems = Array.from(this.findAllElements('.target-node-item'));
        if (targetNodeItems.length === 0) return;

        // Check if all uploads are complete (either completed or failed)
        let allComplete = true;
        let hasAnyCompleted = false;
        let hasAnyFailed = false;
        let uploadingCount = 0;

        const statuses = [];
        targetNodeItems.forEach(item => {
            const statusElement = item.querySelector('.status-indicator');
            if (statusElement) {
                const status = statusElement.textContent;
                statuses.push(status);

                if (status !== 'Completed' && status !== 'Failed') {
                    allComplete = false;
                    if (status === 'Uploading...') {
                        uploadingCount++;
                    }
                }
                if (status === 'Completed') {
                    hasAnyCompleted = true;
                }
                if (status === 'Failed') {
                    hasAnyFailed = true;
                }
            }
        });

        logger.debug('FirmwareUploadComponent: Upload status check:', {
            totalItems: targetNodeItems.length,
            allComplete,
            uploadingCount,
            hasAnyCompleted,
            hasAnyFailed,
            statuses
        });

        // If all uploads are complete, finalize the results
        if (allComplete) {
            logger.debug('FirmwareUploadComponent: All firmware uploads complete, finalizing results');

            // Generate results based on current status
            const results = targetNodeItems.map(item => {
                const nodeIp = item.getAttribute('data-node-ip');
                const nodeName = item.querySelector('.node-name')?.textContent || nodeIp;
                const statusElement = item.querySelector('.status-indicator');
                const status = statusElement?.textContent || 'Unknown';

                return {
                    nodeIp: nodeIp,
                    hostname: nodeName,
                    success: status === 'Completed',
                    error: status === 'Failed' ? 'Upload failed' : undefined,
                    timestamp: new Date().toISOString()
                };
            });

            // Update the header and summary to show final results
            this.displayUploadResults(results);

            // Hide the progress overlay since upload is complete
            this.hideProgressOverlay();

            // Now that all uploads are truly complete (confirmed via websocket), mark upload as complete
            this.viewModel.completeUpload();

            // Reset upload state after a short delay to allow user to see results and re-enable deploy button
            setTimeout(() => {
                this.viewModel.resetUploadState();
                logger.debug('FirmwareUploadComponent: Upload state reset, deploy button should be re-enabled');
            }, 5000);
        } else if (uploadingCount > 0) {
            logger.debug(`FirmwareUploadComponent: ${uploadingCount} uploads still in progress, not finalizing yet`);
        } else {
            logger.debug('FirmwareUploadComponent: Some uploads may have unknown status, but not finalizing yet');
        }
    }

    mount() {
        super.mount();
        
        logger.debug('FirmwareUploadComponent: Mounting...');
        
        // Initialize overlay dialog
        this.initializeOverlayDialog();
        
        // Initialize UI state
        this.updateFileInfo();
        this.updateDeployButton();
        
        logger.debug('FirmwareUploadComponent: Mounted successfully');
    }

    render() {
        // Initial render is handled by the HTML template
        this.updateDeployButton();
    }

    initializeOverlayDialog() {
        // Create overlay container if it doesn't exist
        let overlayContainer = document.getElementById('firmware-upload-overlay-dialog');
        if (!overlayContainer) {
            overlayContainer = document.createElement('div');
            overlayContainer.id = 'firmware-upload-overlay-dialog';
            overlayContainer.className = 'overlay-dialog';
            document.body.appendChild(overlayContainer);
        }

        // Create and initialize the overlay dialog component
        if (!this.overlayDialog) {
            const overlayVM = new ViewModel();
            this.overlayDialog = new OverlayDialogComponent(overlayContainer, overlayVM, this.eventBus);
            this.overlayDialog.mount();
        }
    }

    showConfirmationDialog(options) {
        if (!this.overlayDialog) {
            this.initializeOverlayDialog();
        }
        
        this.overlayDialog.show(options);
    }

    handleFileSelect(event) {
        const file = event.target.files[0];
        this.viewModel.setSelectedFile(file);
    }

    async handleDeploy() {
        const file = this.viewModel.get('selectedFile');
        const targetNodes = this.viewModel.get('targetNodes');
        
        if (!file) {
            this.showConfirmationDialog({
                title: 'No File Selected',
                message: 'Please select a firmware file first.',
                confirmText: 'OK',
                cancelText: null,
                onConfirm: () => {},
                onCancel: null
            });
            return;
        }
        
        if (!targetNodes || targetNodes.length === 0) {
            this.showConfirmationDialog({
                title: 'No Target Nodes',
                message: 'No target nodes available for firmware update.',
                confirmText: 'OK',
                cancelText: null,
                onConfirm: () => {},
                onCancel: null
            });
            return;
        }
        
        // Show confirmation dialog for deployment
        this.showDeploymentConfirmation(file, targetNodes);
    }

    showDeploymentConfirmation(file, targetNodes) {
        const title = 'Deploy Firmware';
        const message = `Upload firmware "${file.name}" to ${targetNodes.length} node(s)?<br><br>Target nodes:<br>${targetNodes.map(n => `• ${n.hostname || n.ip} (${n.ip})`).join('<br>')}<br><br>This will update the firmware on all selected nodes.`;
        
        this.showConfirmationDialog({
            title: title,
            message: message,
            confirmText: 'Deploy',
            cancelText: 'Cancel',
            onConfirm: () => this.performDeployment(file, targetNodes),
            onCancel: () => {}
        });
    }

    async performDeployment(file, targetNodes) {
        try {
            this.viewModel.startUpload();

            // Show progress overlay to block UI interactions
            this.showProgressOverlay();

            // Show upload progress area
            this.showUploadProgress(file, targetNodes);

            // Start batch upload
            const results = await this.performBatchUpload(file, targetNodes);

            // NOTE: Don't display results or reset state here!
            // The upload state should remain active until websocket confirms completion
            // Status updates and finalization happen via websocket messages in checkAndFinalizeUploadResults()
            logger.debug('FirmwareUploadComponent: Firmware upload HTTP requests completed, waiting for websocket status updates');

        } catch (error) {
            logger.error('FirmwareUploadComponent: Firmware deployment failed:', error);
            this.showConfirmationDialog({
                title: 'Deployment Failed',
                message: `Deployment failed: ${error.message}`,
                confirmText: 'OK',
                cancelText: null,
                onConfirm: () => {},
                onCancel: null
            });
            // Only complete upload on error
            this.viewModel.completeUpload();
            this.hideProgressOverlay();
        }
    }

    async performBatchUpload(file, nodes) {
        const results = [];
        const totalNodes = nodes.length;
        let successfulUploads = 0;

        // Initialize all nodes as uploading first
        for (let i = 0; i < nodes.length; i++) {
            const node = nodes[i];
            const nodeIp = node.ip;
            this.updateNodeProgress(i + 1, totalNodes, nodeIp, 'Uploading...');
        }

        for (let i = 0; i < nodes.length; i++) {
            const node = nodes[i];
            const nodeIp = node.ip;

            try {
                // Upload to this node (HTTP call just initiates the upload)
                const result = await this.performSingleUpload(file, nodeIp);

                // Don't immediately mark as completed - wait for websocket status
                logger.debug(`FirmwareUploadComponent: Firmware upload initiated for node ${nodeIp}, waiting for completion status via websocket`);
                results.push(result);

            } catch (error) {
                logger.error(`FirmwareUploadComponent: Failed to upload to node ${nodeIp}:`, error);
                const errorResult = {
                    nodeIp: nodeIp,
                    hostname: node.hostname || nodeIp,
                    success: false,
                    error: error.message,
                    timestamp: new Date().toISOString()
                };
                results.push(errorResult);

                // For HTTP errors, we can immediately mark as failed since the upload didn't start
                this.updateNodeProgress(i + 1, totalNodes, nodeIp, 'Failed');
            }

            // Small delay between uploads
            if (i < nodes.length - 1) {
                await new Promise(resolve => setTimeout(resolve, 1000));
            }
        }

        return results;
    }

    async performSingleUpload(file, nodeIp) {
        try {
            const result = await window.apiClient.uploadFirmware(file, nodeIp);

            // IMPORTANT: This HTTP response is just an acknowledgment that the gateway received the file
            // The actual firmware processing happens asynchronously on the device
            // Status updates will come via WebSocket messages, NOT from this HTTP response
            logger.debug(`FirmwareUploadComponent: HTTP acknowledgment received for ${nodeIp}:`, result);
            logger.debug(`FirmwareUploadComponent: This does NOT mean upload is complete - waiting for WebSocket status updates`);

            return {
                nodeIp: nodeIp,
                hostname: nodeIp,
                httpAcknowledged: true,  // Changed from 'success' to make it clear this is just HTTP ack
                result: result,
                timestamp: new Date().toISOString()
            };

        } catch (error) {
            throw new Error(`Upload to ${nodeIp} failed: ${error.message}`);
        }
    }

    showUploadProgress(file, nodes) {
        // Update the target nodes section header to show upload progress
        const targetNodesSection = this.findElement('.target-nodes-section');
        if (targetNodesSection) {
            const h3 = targetNodesSection.querySelector('h3');
            if (h3) {
                h3.innerHTML = `
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16" style="margin-right:6px; vertical-align: -2px;">
                        <path d="M12 16V4"/>
                        <path d="M8 8l4-4 4 4"/>
                        <path d="M20 16v2a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-2"/>
                    </svg>
                    Firmware Upload Progress (${nodes.length} nodes)
                `;
            }
        }
        
        // Add progress info to the firmware-progress-container
        const container = this.findElement('#firmware-progress-container');
        if (container) {
            const progressHTML = `
                <div class="upload-progress-info">
                    <div class="overall-progress">
                        <div class="progress-bar-container">
                            <div class="progress-bar" id="overall-progress-bar" style="width: 0%; background-color: #fbbf24;"></div>
                        </div>
                        <span class="progress-text">0/${nodes.length} Successful (0%)</span>
                    </div>
                    <div class="progress-summary" id="progress-summary">
                        <span>Status: Upload in progress...</span>
                    </div>
                </div>
            `;
            container.innerHTML = progressHTML;
        }
        
        // Update existing target nodes to show upload status
        this.updateTargetNodesForUpload(nodes);
    }

    updateTargetNodesForUpload(nodes) {
        const targetNodesList = this.findElement('.target-nodes-list');
        if (!targetNodesList) return;
        
        // Update each target node item to show upload status
        targetNodesList.innerHTML = nodes.map(node => `
            <div class="target-node-item" data-node-ip="${node.ip}">
                <div class="node-info">
                    <span class="node-name">${node.hostname || node.ip}</span>
                    <span class="node-ip">${node.ip}</span>
                </div>
                <div class="node-status">
                    <span class="status-indicator uploading">Uploading...</span>
                </div>
            </div>
        `).join('');
    }

    updateNodeProgress(current, total, nodeIp, status) {
        const targetNodeItem = this.findElement(`[data-node-ip="${nodeIp}"]`);
        if (targetNodeItem) {
            const statusElement = targetNodeItem.querySelector('.status-indicator');
            
            if (statusElement) {
                statusElement.textContent = status;
                
                // Update status-specific styling
                statusElement.className = 'status-indicator';
                if (status === 'Completed') {
                    statusElement.classList.add('success');
                } else if (status === 'Failed') {
                    statusElement.classList.add('error');
                } else if (status === 'Uploading...') {
                    statusElement.classList.add('uploading');
                } else if (status === 'Pending...') {
                    statusElement.classList.add('pending');
                }
            }
        }
    }

    updateOverallProgress(successfulUploads, totalNodes) {
        const progressBar = this.findElement('#overall-progress-bar');
        const progressText = this.findElement('.progress-text');

        if (progressBar && progressText) {
            const successPercentage = Math.round((successfulUploads / totalNodes) * 100);
            progressBar.style.width = `${successPercentage}%`;
            progressText.textContent = `${successfulUploads}/${totalNodes} Successful (${successPercentage}%)`;

            // Update progress bar color based on completion
            if (successPercentage === 100) {
                progressBar.style.backgroundColor = '#4ade80';
            } else if (successPercentage > 50) {
                progressBar.style.backgroundColor = '#60a5fa';
            } else {
                progressBar.style.backgroundColor = '#fbbf24';
            }

            // NOTE: Don't update progress summary here for single-node uploads
            // The summary should only be updated via websocket status updates
            // This prevents premature "completed successfully" messages
        }
    }

    displayUploadResults(results) {
        const progressHeader = this.findElement('.progress-header h3');
        const progressSummary = this.findElement('#progress-summary');
        
        if (progressHeader && progressSummary) {
            const successCount = results.filter(r => r.success).length;
            const totalCount = results.length;
            const successRate = Math.round((successCount / totalCount) * 100);
            
            if (totalCount === 1) {
                // Single node upload
                if (successCount === 1) {
                    progressHeader.textContent = `Firmware Upload Complete`;
                    progressSummary.innerHTML = `<span>${window.icon('success', { width: 14, height: 14 })} Upload to ${results[0].hostname || results[0].nodeIp} completed successfully at ${new Date().toLocaleTimeString()}</span>`;
                } else {
                    progressHeader.textContent = `Firmware Upload Failed`;
                    progressSummary.innerHTML = `<span>${window.icon('error', { width: 14, height: 14 })} Upload to ${results[0].hostname || results[0].nodeIp} failed at ${new Date().toLocaleTimeString()}</span>`;
                }
            } else if (successCount === totalCount) {
                // Multi-node upload - all successful
                progressHeader.textContent = `Firmware Upload Complete (${successCount}/${totalCount} Successful)`;
                progressSummary.innerHTML = `<span>${window.icon('success', { width: 14, height: 14 })} All uploads completed successfully at ${new Date().toLocaleTimeString()}</span>`;
            } else {
                // Multi-node upload - some failed
                progressHeader.textContent = `Firmware Upload Results (${successCount}/${totalCount} Successful)`;
                progressSummary.innerHTML = `<span>${window.icon('warning', { width: 14, height: 14 })} Upload completed with ${totalCount - successCount} failure(s) at ${new Date().toLocaleTimeString()}</span>`;
            }
        }
    }

    updateFileInfo() {
        const file = this.viewModel.get('selectedFile');
        const fileInfo = this.findElement('#file-info');
        
        if (file) {
            fileInfo.textContent = `${file.name} (${(file.size / 1024).toFixed(1)}KB)`;
            fileInfo.classList.add('has-file');
        } else {
            fileInfo.textContent = 'No file selected';
            fileInfo.classList.remove('has-file');
        }
        
        this.updateDeployButton();
    }

    updateDeployButton() {
        const deployBtn = this.findElement('#deploy-btn');
        if (deployBtn) {
            const file = this.viewModel.get('selectedFile');
            const targetNodes = this.viewModel.get('targetNodes');
            const isUploading = this.viewModel.get('isUploading');
            
            deployBtn.disabled = !file || !targetNodes || targetNodes.length === 0 || isUploading;
        }
    }

    updateUploadState() {
        const isUploading = this.viewModel.get('isUploading');
        const deployBtn = this.findElement('#deploy-btn');
        
        if (deployBtn) {
            deployBtn.disabled = isUploading;
            if (isUploading) {
                deployBtn.classList.add('loading');
                // Update button text while keeping the SVG icon
                const iconSvg = deployBtn.querySelector('svg');
                deployBtn.innerHTML = '';
                if (iconSvg) {
                    deployBtn.appendChild(iconSvg);
                }
                deployBtn.appendChild(document.createTextNode(' Deploying...'));
            } else {
                deployBtn.classList.remove('loading');
                // Restore original button content with SVG icon
                deployBtn.innerHTML = `
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" style="margin-right:6px; vertical-align: -2px;">
                        <path d="M12 16V4"/>
                        <path d="M8 8l4-4 4 4"/>
                        <path d="M20 16v2a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-2"/>
                    </svg>
                    Deploy
                `;
            }
        }
    }

    updateUploadProgress() {
        // This will be implemented when we add upload progress tracking
    }

    updateUploadResults() {
        // This will be implemented when we add upload results display
    }

    showProgressOverlay() {
        // Create overlay element that only covers the left side (main content area)
        const overlay = document.createElement('div');
        overlay.id = 'firmware-upload-overlay';
        overlay.className = 'firmware-upload-overlay';
        overlay.innerHTML = `
            <div class="overlay-content">
                <div class="overlay-spinner">
                    <svg class="spinner" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <circle cx="12" cy="12" r="10"/>
                    </svg>
                </div>
                <div class="overlay-text">Firmware upload in progress...</div>
                <div class="overlay-subtext">Check the drawer for detailed progress</div>
            </div>
        `;
        
        // Add to body
        document.body.appendChild(overlay);
        
        // Check if drawer is open and adjust overlay accordingly
        const drawer = document.querySelector('.details-drawer');
        if (drawer && drawer.classList.contains('open')) {
            overlay.classList.add('drawer-open');
        }
        
        // Block ESC key during upload
        this.blockEscapeKey();
        
        // Block drawer close button during upload
        this.blockDrawerCloseButton();
        
        // Block choose file button during upload
        this.blockChooseFileButton();
        
        
        // Store reference for cleanup
        this.progressOverlay = overlay;
    }

    blockDrawerCloseButton() {
        // Find the drawer close button
        const closeButton = document.querySelector('.drawer-close');
        if (closeButton) {
            // Store original state
            this.originalCloseButtonDisabled = closeButton.disabled;
            this.originalCloseButtonStyle = closeButton.style.cssText;
            
            // Disable the close button
            closeButton.disabled = true;
            closeButton.style.opacity = '0.5';
            closeButton.style.cursor = 'not-allowed';
            closeButton.style.pointerEvents = 'none';
            
            // Add visual indicator that it's disabled
            closeButton.title = 'Cannot close during firmware upload';
        }
    }

    unblockDrawerCloseButton() {
        // Restore the drawer close button
        const closeButton = document.querySelector('.drawer-close');
        if (closeButton) {
            // Restore original state
            closeButton.disabled = this.originalCloseButtonDisabled || false;
            closeButton.style.cssText = this.originalCloseButtonStyle || '';
            closeButton.title = 'Close';
        }
    }

    blockChooseFileButton() {
        // Find the choose file button
        const chooseFileButton = document.querySelector('.upload-btn-compact');
        if (chooseFileButton) {
            // Store original state
            this.originalChooseFileButtonDisabled = chooseFileButton.disabled;
            this.originalChooseFileButtonStyle = chooseFileButton.style.cssText;
            
            // Disable the choose file button
            chooseFileButton.disabled = true;
            chooseFileButton.style.opacity = '0.5';
            chooseFileButton.style.cursor = 'not-allowed';
            chooseFileButton.style.pointerEvents = 'none';
            
            // Add visual indicator that it's disabled
            chooseFileButton.title = 'Cannot change file during upload';
        }
    }

    unblockChooseFileButton() {
        // Restore the choose file button
        const chooseFileButton = document.querySelector('.upload-btn-compact');
        if (chooseFileButton) {
            // Restore original state
            chooseFileButton.disabled = this.originalChooseFileButtonDisabled || false;
            chooseFileButton.style.cssText = this.originalChooseFileButtonStyle || '';
            chooseFileButton.title = 'Choose File';
        }
    }

    hideTargetNodesSection() {
        // Find the target nodes section
        const targetNodesSection = document.querySelector('.target-nodes-section');
        if (targetNodesSection) {
            // Store original state
            this.originalTargetNodesSectionDisplay = targetNodesSection.style.display;
            
            // Hide the target nodes section
            targetNodesSection.style.display = 'none';
        }
    }

    showTargetNodesSection() {
        // Restore the target nodes section
        const targetNodesSection = document.querySelector('.target-nodes-section');
        if (targetNodesSection) {
            // Restore original state
            targetNodesSection.style.display = this.originalTargetNodesSectionDisplay || '';
        }
    }

    blockEscapeKey() {
        // Create a keydown event listener that prevents ESC from closing the drawer
        this.escapeKeyHandler = (event) => {
            if (event.key === 'Escape') {
                event.preventDefault();
                event.stopPropagation();
                event.stopImmediatePropagation();
                return false;
            }
        };
        
        // Add the event listener with capture=true to intercept before drawer's handler
        document.addEventListener('keydown', this.escapeKeyHandler, true);
    }

    unblockEscapeKey() {
        // Remove the ESC key blocker
        if (this.escapeKeyHandler) {
            document.removeEventListener('keydown', this.escapeKeyHandler, true);
            this.escapeKeyHandler = null;
        }
    }

    hideProgressOverlay() {
        if (this.progressOverlay) {
            this.progressOverlay.remove();
            this.progressOverlay = null;
        }
        
        // Unblock ESC key
        this.unblockEscapeKey();
        
        // Unblock drawer close button
        this.unblockDrawerCloseButton();
        
        // Unblock choose file button
        this.unblockChooseFileButton();
        
    }
}

window.FirmwareUploadComponent = FirmwareUploadComponent;
