(function() {
    let uploadQueue = [];
    let isUploading = false;
    let logoClicks = 0;
    let lastLogoClick = 0;
    let sharedTextBuffer = "";
    let isWsConnected = false;

    // Utility Functions
    function formatBytes(bytes, decimals = 1) {
        if (bytes === 0) return '0 B';
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
    }

    function formatDuration(seconds) {
        if (!seconds || seconds < 1) return '< 1s';
        if (!isFinite(seconds)) return 'Calculating...';
        seconds = Math.round(seconds);
        const h = Math.floor(seconds / 3600);
        const m = Math.floor((seconds % 3600) / 60);
        const s = seconds % 60;
        
        if (h > 0) return `${h}h ${m}m`;
        if (m > 0) return `${m}m ${s}s`;
        return `${s}s`;
    }

    function getFileIcon(filename) {
        const ext = filename.split('.').pop().toLowerCase();
        
        const video = ['mp4','mkv','avi','mov','webm'];
        const image = ['jpg','jpeg','png','gif','svg','webp'];
        const audio = ['mp3','wav','flac','aac','ogg'];
        const archive = ['zip','rar','7z','tar','gz'];
        const code = ['js','py','html','css','json'];
        
        // Lucide styling: stroke color matches text color
        const svgAttr = 'width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide-icon"';

        if (video.includes(ext)) {
            return `<svg ${svgAttr}><path d="m22 8-6 4 6 4V8Z"/><rect width="14" height="12" x="2" y="6" rx="2" ry="2"/></svg>`;
        }
        if (image.includes(ext)) {
            return `<svg ${svgAttr}><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>`;
        }
        if (audio.includes(ext)) {
            return `<svg ${svgAttr}><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg>`;
        }
        if (ext === 'pdf') {
            return `<svg ${svgAttr}><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/></svg>`;
        }
        if (archive.includes(ext)) {
            return `<svg ${svgAttr}><path d="M16.5 9.4 7.55 4.24"/><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" x2="12" y1="22.08" y2="12"/></svg>`;
        }
        if (code.includes(ext)) {
            return `<svg ${svgAttr}><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>`;
        }
        return `<svg ${svgAttr}><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><line x1="9" x2="15" y1="9" y2="9"/><line x1="9" x2="15" y1="13" y2="13"/><line x1="9" x2="11" y1="17" y2="17"/></svg>`;
    }

    function initUploadZone() {
        const uploadZone = document.getElementById('upload-zone');
        const fileInput = document.getElementById('file-input');
        const browseBtn = document.getElementById('browse-btn');

        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            document.body.addEventListener(eventName, preventDefaults, false);
        });

        function preventDefaults(e) {
            e.preventDefault();
            e.stopPropagation();
        }

        ['dragenter', 'dragover'].forEach(eventName => {
            if (uploadZone) uploadZone.addEventListener(eventName, highlight, false);
        });

        ['dragleave', 'drop'].forEach(eventName => {
            if (uploadZone) uploadZone.addEventListener(eventName, unhighlight, false);
        });

        function highlight(e) {
            uploadZone.classList.add('drag-over');
        }

        function unhighlight(e) {
            uploadZone.classList.remove('drag-over');
        }

        if (uploadZone) uploadZone.addEventListener('drop', handleDrop, false);

        function handleDrop(e) {
            const dt = e.dataTransfer;
            const files = dt.files;
            handleFiles(files);
        }

        if (browseBtn) {
            browseBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (fileInput) fileInput.click();
            });
        }

        if (uploadZone) {
            uploadZone.addEventListener('click', (e) => {
                if (e.target !== browseBtn) {
                    if (fileInput) fileInput.click();
                }
            });
        }

        if (fileInput) {
            fileInput.addEventListener('change', function() {
                handleFiles(this.files);
            });
        }
    }

    function handleFiles(fileList) {
        if (fileList && fileList.length > 0) {
            for (let i = 0; i < fileList.length; i++) {
                uploadQueue.push(fileList[i]);
            }
            if (!isUploading) {
                processNextUpload();
            }
        }
    }

    function processNextUpload() {
        if (uploadQueue.length === 0) {
            isUploading = false;
            // Clear progress section state after queue finishes
            setTimeout(() => {
                const progressSection = document.getElementById('progress-section');
                if (progressSection && !isUploading) {
                    progressSection.classList.remove('active');
                }
            }, 3000);
            return;
        }

        isUploading = true;
        const file = uploadQueue.shift();
        uploadFile(file, () => {
            processNextUpload();
        }, () => {
            // On error, pause briefly so user sees the message, then process next file
            setTimeout(processNextUpload, 2000);
        });
    }

    function uploadFile(file, onComplete, onError) {
        const progressSection = document.getElementById('progress-section');
        const progressFilename = document.getElementById('progress-filename');
        const progressPercent = document.getElementById('progress-percent');
        const progressBarFill = document.getElementById('progress-bar-fill');
        const progressTransferred = document.getElementById('progress-transferred');
        const progressSpeed = document.getElementById('progress-speed');
        const progressEta = document.getElementById('progress-eta');

        if (progressSection) progressSection.classList.add('active');
        
        const queueHint = uploadQueue.length > 0 ? ` (+${uploadQueue.length} more)` : '';
        if (progressFilename) progressFilename.textContent = file.name + queueHint;
        
        if (progressBarFill) {
            progressBarFill.style.width = '0%';
            progressBarFill.classList.remove('complete', 'error');
        }
        if (progressSection) progressSection.classList.remove('complete', 'error');

        const xhr = new XMLHttpRequest();
        const formData = new FormData();
        formData.append('file', file);
        
        let lastLoaded = 0;
        let lastTime = Date.now();
        let speeds = []; 
        
        xhr.upload.addEventListener('progress', function(e) {
            if (e.lengthComputable) {
                const percent = (e.loaded / e.total) * 100;
                if (progressBarFill) progressBarFill.style.width = percent + '%';
                if (progressPercent) progressPercent.textContent = Math.round(percent) + '%';
                if (progressTransferred) progressTransferred.textContent = formatBytes(e.loaded) + ' / ' + formatBytes(e.total);
                
                const now = Date.now();
                const timeDelta = (now - lastTime) / 1000;
                if (timeDelta > 0.1) {
                    const byteDelta = e.loaded - lastLoaded;
                    const speed = byteDelta / timeDelta;
                    speeds.push(speed);
                    if (speeds.length > 5) speeds.shift();
                    const avgSpeed = speeds.reduce((a,b) => a+b, 0) / speeds.length;
                    
                    if (progressSpeed) progressSpeed.textContent = formatBytes(avgSpeed) + '/s';
                    
                    const remaining = e.total - e.loaded;
                    const eta = remaining / avgSpeed;
                    if (progressEta) progressEta.textContent = formatDuration(eta) + ' remaining';
                    
                    lastLoaded = e.loaded;
                    lastTime = now;
                }
            }
        });
        
        xhr.addEventListener('load', function() {
            if (xhr.status >= 200 && xhr.status < 300) {
                if (progressBarFill) {
                    progressBarFill.style.width = '100%';
                    progressBarFill.classList.add('complete');
                }
                if (progressSection) progressSection.classList.add('complete');
                if (progressSpeed) progressSpeed.textContent = 'Complete';
                if (progressEta) progressEta.textContent = '✓';
                
                setTimeout(() => {
                    loadFileList();
                    if (onComplete) onComplete();
                }, 500);
            } else {
                handleError();
            }
        });
        
        xhr.addEventListener('error', function() {
            handleError();
        });
        
        xhr.addEventListener('abort', function() {
            handleError();
        });

        function handleError() {
            if (progressBarFill) progressBarFill.classList.add('error');
            if (progressSection) progressSection.classList.add('error');
            if (progressSpeed) progressSpeed.textContent = 'Failed';
            if (progressEta) progressEta.textContent = 'Upload error';
            if (onError) onError();
        }
        
        xhr.open('POST', '/upload');
        xhr.send(formData);
    }

    async function loadFileList() {
        try {
            const response = await fetch('/files');
            if (!response.ok) throw new Error('Network response was not ok');
            const data = await response.json();
            renderFileList(data.files || [], data.count || 0);
        } catch (err) {
            console.warn('Could not load file list:', err);
            const fileList = document.getElementById('file-list');
            if (fileList) {
                fileList.innerHTML = '<li class="error-msg">Error loading file list.</li>';
            }
        }
    }

    let lastFilesHash = "";

    function renderFileList(files, count) {
        const fileListElement = document.getElementById('file-list');
        const fileCount = document.getElementById('file-count');
        const fileTotalSize = document.getElementById('file-total-size');

        if (fileCount) fileCount.innerHTML = `<span>${count}</span> files`;

        let totalSize = 0;
        files.forEach(f => {
            totalSize += f.size || 0;
        });

        if (fileTotalSize) fileTotalSize.innerHTML = `<span>${formatBytes(totalSize)}</span> total`;

        if (!fileListElement) return;

        const currentHash = files.map(f => `${f.name}-${f.size}-${f.modified}`).join('|');
        if (currentHash === lastFilesHash && fileListElement.children.length > 0) {
            return; // Skip DOM re-render if file list hasn't changed
        }
        lastFilesHash = currentHash;

        fileListElement.innerHTML = '';

        if (files.length === 0) {
            fileListElement.innerHTML = '<li class="empty-msg">No files available.</li>';
            return;
        }

        files.forEach(file => {
            const li = document.createElement('li');
            li.className = 'file-item';

            const iconSpan = document.createElement('span');
            iconSpan.className = 'file-icon';
            iconSpan.innerHTML = getFileIcon(file.name);

            // Create container for name + metadata
            const infoDiv = document.createElement('div');
            infoDiv.className = 'file-info';

            const nameSpan = document.createElement('span');
            nameSpan.className = 'file-name';
            nameSpan.textContent = file.name;
            nameSpan.title = file.name;

            const metaDiv = document.createElement('div');
            metaDiv.className = 'file-meta';

            const sizeSpan = document.createElement('span');
            sizeSpan.className = 'file-size';
            sizeSpan.textContent = formatBytes(file.size);

            const separatorSpan = document.createElement('span');
            separatorSpan.className = 'meta-separator';
            separatorSpan.innerHTML = ' &middot; ';

            const dateSpan = document.createElement('span');
            dateSpan.className = 'file-date';
            const d = new Date(file.modified || Date.now());
            dateSpan.textContent = d.toLocaleDateString() + ' ' + d.toLocaleTimeString();

            metaDiv.appendChild(sizeSpan);
            metaDiv.appendChild(separatorSpan);
            metaDiv.appendChild(dateSpan);

            infoDiv.appendChild(nameSpan);
            infoDiv.appendChild(metaDiv);

            const actionSpan = document.createElement('span');
            actionSpan.className = 'file-actions';

            const downloadBtn = document.createElement('button');
            downloadBtn.className = 'download-btn';
            downloadBtn.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>`;
            downloadBtn.title = 'Download File';
            downloadBtn.onclick = (e) => {
                e.stopPropagation();
                downloadFile(file.name);
            };

            const deleteBtn = document.createElement('button');
            deleteBtn.className = 'delete-btn';
            deleteBtn.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>`;
            deleteBtn.title = 'Delete File';
            deleteBtn.onclick = (e) => {
                e.stopPropagation();
                showConfirm(`Delete "${file.name}"?`, async () => {
                    await deleteFile(file.name);
                });
            };

            actionSpan.appendChild(downloadBtn);
            actionSpan.appendChild(deleteBtn);

            li.appendChild(iconSpan);
            li.appendChild(infoDiv);
            li.appendChild(actionSpan);

            fileListElement.appendChild(li);
        });
    }

    async function deleteFile(filename) {
        try {
            const response = await fetch('/delete/' + encodeURIComponent(filename), {
                method: 'DELETE'
            });
            if (response.ok) {
                loadFileList();
            } else {
                const data = await response.json();
                alert('Error deleting file: ' + (data.detail || 'unknown error'));
            }
        } catch (err) {
            console.error('Delete failed:', err);
            alert('Failed to connect to server to delete file.');
        }
    }

    function showConfirm(message, onConfirm) {
        const overlay = document.getElementById('confirm-modal');
        const msgElem = document.getElementById('confirm-message');
        const okBtn = document.getElementById('confirm-ok');
        const cancelBtn = document.getElementById('confirm-cancel');

        if (!overlay || !msgElem || !okBtn || !cancelBtn) return;

        msgElem.textContent = message;
        overlay.classList.add('active');

        function cleanup() {
            overlay.classList.remove('active');
            okBtn.onclick = null;
            cancelBtn.onclick = null;
            overlay.onclick = null;
        }

        okBtn.onclick = () => {
            cleanup();
            onConfirm();
        };

        cancelBtn.onclick = () => {
            cleanup();
        };

        overlay.onclick = (e) => {
            if (e.target === overlay) {
                cleanup();
            }
        };
    }

    function downloadFile(filename) {
        const a = document.createElement('a');
        a.href = '/download/' + encodeURIComponent(filename);
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    }

    let selectedIpOverride = null;

    async function checkConnection() {
        const statusDot = document.getElementById('status-dot');
        const statusText = document.getElementById('status-text');
        const statusBar = document.getElementById('status-bar');
        const connectionUrlText = document.getElementById('connection-url-text');
        const qrCodeImg = document.getElementById('qr-code-img');
        const ipContainer = document.getElementById('ip-selector-container');
        const ipList = document.getElementById('ip-pills-list');

        try {
            const response = await fetch('/info');
            if (response.ok) {
                const data = await response.json();
                const port = data.port || '2703';
                const allIps = data.all_ips || [];

                // Use selected IP or fallback to current primary local_ip
                const activeIp = (selectedIpOverride && allIps.includes(selectedIpOverride)) ? selectedIpOverride : (data.local_ip || '127.0.0.1');
                const activeUrl = `http://${activeIp}:${port}`;

                if (statusDot) {
                    statusDot.style.backgroundColor = '';
                }
                if (statusText) {
                    statusText.textContent = 'Connected  \u00B7  ' + activeIp + ':' + port;
                }
                if (statusBar) {
                    statusBar.classList.remove('disconnected');
                }
                if (connectionUrlText) {
                    connectionUrlText.textContent = activeUrl;
                }
                if (qrCodeImg) {
                    qrCodeImg.src = `/qr?ip=${encodeURIComponent(activeIp)}`;
                }

                // Render IP Selector Pills if multiple IP addresses exist
                if (allIps.length > 1 && ipContainer && ipList) {
                    ipContainer.classList.remove('hidden');
                    ipList.innerHTML = '';
                    allIps.forEach(ip => {
                        const pill = document.createElement('button');
                        pill.className = 'ip-pill' + (ip === activeIp ? ' active' : '');
                        pill.textContent = ip;
                        pill.onclick = (e) => {
                            e.stopPropagation();
                            selectedIpOverride = ip;
                            checkConnection();
                        };
                        ipList.appendChild(pill);
                    });
                } else if (ipContainer) {
                    ipContainer.classList.add('hidden');
                }
            } else {
                throw new Error('Not ok');
            }
        } catch (err) {
            if (statusDot) {
                statusDot.style.backgroundColor = '';
            }
            if (statusText) {
                statusText.textContent = 'Disconnected  \u00B7  Reconnecting...';
            }
            if (statusBar) {
                statusBar.classList.add('disconnected');
            }
        }
    }

    function initConnectionCard() {
        const connectionCard = document.getElementById('connection-card');
        if (connectionCard) {
            // Hide connection QR code card on mobile browsers
            const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
            if (!isLocalhost) {
                connectionCard.style.display = 'none';
            }
        }

        const copyUrlBtn = document.getElementById('copy-url-btn');
        const connectionUrlText = document.getElementById('connection-url-text');
        if (copyUrlBtn && connectionUrlText) {
            const originalHTML = copyUrlBtn.innerHTML;
            copyUrlBtn.onclick = (e) => {
                e.stopPropagation();
                const textToCopy = connectionUrlText.textContent.trim();
                copyTextToClipboard(textToCopy, copyUrlBtn, originalHTML);
            };
        }
    }

    async function loadSharedText() {
        try {
            const response = await fetch('/share-text');
            if (response.ok) {
                const data = await response.json();
                displaySharedText(data.text || "");
            }
        } catch (err) {
            console.warn('Could not load shared text:', err);
        }
    }

    async function shareText(text) {
        const shareBtn = document.getElementById('clipboard-share-btn');
        if (shareBtn) shareBtn.disabled = true;
        
        try {
            const response = await fetch('/share-text', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ text: text })
            });
            if (response.ok) {
                const textarea = document.getElementById('clipboard-textarea');
                if (textarea) textarea.value = '';
            } else {
                alert('Failed to share text.');
            }
        } catch (err) {
            console.error('Share text failed:', err);
            alert('Failed to connect to server.');
        } finally {
            if (shareBtn) shareBtn.disabled = false;
        }
    }

    function displaySharedText(text) {
        sharedTextBuffer = text;
        const container = document.getElementById('shared-text-display-container');
        const textContent = document.getElementById('shared-text-content');
        const warningCard = document.getElementById('clipboard-warning-card');

        if (!container) return;

        if (!text) {
            container.classList.add('hidden');
            return;
        }

        container.classList.remove('hidden');

        // Threshold Switcher Guard (50,000 characters)
        if (text.length < 50000) {
            if (textContent) {
                textContent.textContent = text;
                textContent.classList.remove('hidden');
            }
            if (warningCard) warningCard.classList.add('hidden');
        } else {
            if (textContent) textContent.classList.add('hidden');
            if (warningCard) warningCard.classList.remove('hidden');
        }

        // Smart Parsing Engine
        runSmartParser(text);
    }

    function downloadTextPayload(text, filename = "clipboard.txt") {
        const blob = new Blob([text], { type: "text/plain;charset=utf-8" });
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    }

    function copyTextToClipboard(text, buttonElem, originalHTML) {
        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(text).then(() => {
                showFeedback();
            }).catch(err => {
                fallbackCopy();
            });
        } else {
            fallbackCopy();
        }

        function fallbackCopy() {
            const textArea = document.createElement("textarea");
            textArea.value = text;
            textArea.style.top = "0";
            textArea.style.left = "0";
            textArea.style.position = "fixed";
            textArea.style.opacity = "0";
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            try {
                const successful = document.execCommand('copy');
                if (successful) {
                    showFeedback();
                } else {
                    console.error("execCommand copy returned false");
                }
            } catch (err) {
                console.error("Fallback copy failed:", err);
            }
            document.body.removeChild(textArea);
        }

        function showFeedback() {
            if (buttonElem) {
                buttonElem.innerHTML = `✓ Copied!`;
                buttonElem.style.color = '#00ff66';
                setTimeout(() => {
                    buttonElem.innerHTML = originalHTML;
                    buttonElem.style.color = '';
                }, 2000);
            }
        }
    }

    function runSmartParser(text) {
        const chipsContainer = document.getElementById('smart-chips-container');
        const chipsList = document.getElementById('smart-chips-list');

        if (!chipsContainer || !chipsList) return;

        chipsList.innerHTML = '';

        // Regex definitions
        const urlRegex = /(https?:\/\/[^\s]+|www\.[^\s]+|[a-zA-Z0-9.-]+\.(?:com|in|net|org|edu|gov|io|co|xyz|me)(?:\/[^\s]*)?)/gi;
        const phoneRegex = /(?:\+91[\s-]?|0[\s-]?)?[6-9](?:[\s-]?\d){9}\b/g; // Indian Standard Phone format (allows spaces/hyphens inside digits)
        const otpRegex = /\b\d{4,6}\b/g; // Standalone 4-6 digit numeric OTPs

        const urls = text.match(urlRegex) || [];
        const phones = text.match(phoneRegex) || [];
        const otps = text.match(otpRegex) || [];

        // Clean URLs from trailing punctuation
        const cleanUrls = urls.map(url => url.replace(/[.,?!:;)]+$/, ''));
        
        // Clean phone numbers: remove whitespaces, hyphens
        const cleanPhones = phones.map(p => p.trim());

        const uniqueUrls = [...new Set(cleanUrls)];
        const uniquePhones = [...new Set(cleanPhones)];
        const uniqueOtps = [...new Set(otps)];

        let chipCount = 0;

        // Render URL chips
        uniqueUrls.forEach(url => {
            chipCount++;
            const chip = document.createElement('a');
            chip.className = 'smart-chip';
            let href = url;
            if (!/^https?:\/\//i.test(url)) {
                href = 'https://' + url;
            }
            chip.href = href;
            chip.target = '_blank';
            chip.innerHTML = `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg> Open Link`;
            chipsList.appendChild(chip);
        });

        // Render Phone chips
        uniquePhones.forEach(phone => {
            chipCount++;
            const chip = document.createElement('a');
            chip.className = 'smart-chip';
            chip.href = `tel:${phone.replace(/[^\d+]/g, '')}`;
            chip.innerHTML = `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg> Call ${phone}`;
            chipsList.appendChild(chip);
        });

        // Render OTP chips
        uniqueOtps.forEach(otp => {
            chipCount++;
            const chip = document.createElement('button');
            chip.className = 'smart-chip';
            const originalHTML = `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg> Copy OTP (${otp})`;
            chip.innerHTML = originalHTML;
            chip.onclick = (e) => {
                e.stopPropagation();
                copyTextToClipboard(otp, chip, originalHTML);
            };
            chipsList.appendChild(chip);
        });

        if (chipCount > 0) {
            chipsContainer.classList.remove('hidden');
        } else {
            chipsContainer.classList.add('hidden');
        }
    }

    function initEasterEgg() {
        const logo = document.getElementById('logo');
        const creditsModal = document.getElementById('credits-modal');
        const closeBtn = document.getElementById('credits-close');

        if (!logo || !creditsModal || !closeBtn) return;

        logo.addEventListener('click', async function(e) {
            e.preventDefault();
            const now = Date.now();
            if (now - lastLogoClick > 3000) {
                logoClicks = 0;
            }
            logoClicks++;
            lastLogoClick = now;

            if (logoClicks === 7) {
                logoClicks = 0; // Reset
                creditsModal.classList.add('active');
                await updateSystemStats();
            }
        });

        closeBtn.addEventListener('click', function() {
            creditsModal.classList.remove('active');
        });

        creditsModal.onclick = (e) => {
            if (e.target === creditsModal) {
                creditsModal.classList.remove('active');
            }
        };
    }

    async function updateSystemStats() {
        const termPort = document.getElementById('term-port');
        const termStream = document.getElementById('term-stream');
        const termActive = document.getElementById('term-active');
        const termWs = document.getElementById('term-ws');

        if (termPort) termPort.textContent = '2703';
        if (termStream) termStream.textContent = 'Ready';
        if (termWs) {
            termWs.textContent = isWsConnected ? 'Connected' : 'Disconnected';
            termWs.style.color = isWsConnected ? '#00ff66' : '#ff5f56';
        }

        try {
            const infoRes = await fetch('/info');
            if (infoRes.ok) {
                const infoData = await infoRes.json();
                if (termPort && infoData.port) {
                    termPort.textContent = infoData.port;
                }
            }
        } catch (e) {
            console.warn('Failed to query info metrics:', e);
        }

        try {
            const transfersRes = await fetch('/transfers');
            if (transfersRes.ok) {
                const transfersData = await transfersRes.json();
                const list = transfersData.transfers || [];
                const running = list.filter(t => t.status === 'running' || t.status === 'active');
                if (termActive) {
                    termActive.textContent = running.length + (running.length === 1 ? ' Stream' : ' Streams');
                    termActive.style.color = running.length > 0 ? '#fbbf24' : '';
                }
                if (termStream) {
                    termStream.textContent = running.length > 0 ? 'Active' : 'Ready';
                    termStream.style.color = running.length > 0 ? '#fbbf24' : '';
                }
            }
        } catch (e) {
            console.warn('Failed to query transfers metrics:', e);
        }
    }

    function initWebSocket() {
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const wsUrl = `${protocol}//${window.location.host}/ws`;
        let ws;

        try {
            ws = new WebSocket(wsUrl);

            ws.onopen = function() {
                isWsConnected = true;
                const statusLabel = document.getElementById('term-ws');
                if (statusLabel) {
                    statusLabel.textContent = 'CONNECTED';
                    statusLabel.style.color = '#00ff66';
                }
            };

            ws.onmessage = function(event) {
                if (event.data === 'refresh') {
                    loadFileList();
                } else if (event.data === 'text_refresh') {
                    loadSharedText();
                }
            };

            ws.onclose = function() {
                isWsConnected = false;
                const statusLabel = document.getElementById('term-ws');
                if (statusLabel) {
                    statusLabel.textContent = 'DISCONNECTED';
                    statusLabel.style.color = '#ff5f56';
                }
                // Reconnect after 3 seconds if connection drops
                setTimeout(initWebSocket, 3000);
            };

            ws.onerror = function() {
                ws.close();
            };
        } catch (err) {
            isWsConnected = false;
            setTimeout(initWebSocket, 5000);
        }
    }

    function init() {
        initConnectionCard();
        initUploadZone();
        loadFileList();
        checkConnection();
        initWebSocket();
        initEasterEgg();

        // Load shared text on startup
        loadSharedText();

        // Clipboard listeners
        const shareBtn = document.getElementById('clipboard-share-btn');
        const textarea = document.getElementById('clipboard-textarea');
        const copyBtn = document.getElementById('clipboard-copy-btn');
        const downloadBtn = document.getElementById('clipboard-download-btn');
        const copyAnywayBtn = document.getElementById('clipboard-copy-anyway-btn');

        if (shareBtn && textarea) {
            shareBtn.onclick = () => {
                const text = textarea.value.trim();
                if (text) {
                    shareText(text);
                }
            };

            textarea.onkeydown = (e) => {
                if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
                    e.preventDefault();
                    const text = textarea.value.trim();
                    if (text) {
                        shareText(text);
                    }
                }
            };
        }

        if (copyBtn) {
            const originalHTML = copyBtn.innerHTML;
            copyBtn.onclick = () => {
                copyTextToClipboard(sharedTextBuffer, copyBtn, originalHTML);
            };
        }

        const clearBtn = document.getElementById('clipboard-clear-btn');
        if (clearBtn) {
            clearBtn.onclick = () => {
                showConfirm("Clear shared text from all devices?", () => {
                    shareText("");
                });
            };
        }

        if (downloadBtn) {
            downloadBtn.onclick = () => {
                downloadTextPayload(sharedTextBuffer);
            };
        }

        if (copyAnywayBtn) {
            const originalHTML = copyAnywayBtn.innerHTML;
            copyAnywayBtn.onclick = () => {
                copyTextToClipboard(sharedTextBuffer, copyAnywayBtn, originalHTML);
            };
        }

        const refreshBtn = document.getElementById('refresh-btn');
        if (refreshBtn) {
            refreshBtn.addEventListener('click', function() {
                refreshBtn.classList.add('spinning');
                loadFileList().then(function() {
                    setTimeout(function() {
                        refreshBtn.classList.remove('spinning');
                    }, 600);
                });
            });
        }

        // Refresh instantly when user tabs back or unlocks their device
        window.addEventListener('focus', function() {
            loadFileList();
            checkConnection();
            loadSharedText();
        });

        // Auto-shutdown server ONLY when PC/Laptop browser tab is closed (not mobile)
        window.addEventListener('beforeunload', function() {
            const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
            if (isLocalhost && navigator.sendBeacon) {
                navigator.sendBeacon('/shutdown');
            }
        });

        // Polling interval acts only as a backup fallback
        setInterval(checkConnection, 10000);
        setInterval(loadFileList, 20000);
    }

    document.addEventListener('DOMContentLoaded', init);
})();
