<!DOCTYPE html>
<html>
<head>
    <title>YT Mixer - Audio Playlist Mixer</title>
    <style>
        body {
            background: #111;
            color: #eee;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            padding: 20px;
            max-width: 900px;
            margin: 0 auto;
        }
        
        h1 {
            text-align: center;
            margin-bottom: 30px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }
        
        .setup-form {
            background: #222;
            padding: 30px;
            border-radius: 12px;
            margin-bottom: 30px;
            border: 1px solid #444;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
            color: #aaa;
        }
        
        .form-group input {
            width: 100%;
            padding: 12px;
            background: #333;
            border: 1px solid #555;
            border-radius: 6px;
            color: #eee;
            font-size: 14px;
            box-sizing: border-box;
        }
        
        .form-group input:focus {
            outline: none;
            border-color: #667eea;
        }
        
        .btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 12px 32px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            font-weight: bold;
            transition: transform 0.2s;
        }
        
        .btn:hover {
            transform: translateY(-2px);
        }
        
        .btn:active {
            transform: translateY(0);
        }
        
        .player-section {
            background: #222;
            padding: 30px;
            border-radius: 12px;
            border: 1px solid #444;
            display: none;
        }
        
        .player-section.active {
            display: block;
        }
        
        .big-play-btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border: none;
            color: white;
            font-size: 4em;
            padding: 50px;
            border-radius: 50%;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
            width: 180px;
            height: 180px;
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 20px auto;
            border: 3px solid rgba(255, 255, 255, 0.3);
        }
        
        .big-play-btn:hover {
            transform: scale(1.05);
        }
        
        audio {
            width: 100%;
            margin: 20px 0;
        }
        
        .controls {
            display: flex;
            gap: 10px;
            justify-content: center;
            margin: 20px 0;
        }
        
        .controls button {
            background: #333;
            color: #eee;
            border: 1px solid #555;
            padding: 12px 24px;
            border-radius: 6px;
            cursor: pointer;
            transition: background 0.2s;
        }
        
        .controls button:hover {
            background: #444;
        }
        
        .status {
            background: #1a1a1a;
            padding: 20px;
            border-radius: 8px;
            margin-top: 20px;
            font-family: monospace;
            font-size: 13px;
            line-height: 1.8;
        }
        
        .bookmark-info {
            background: #2a2a2a;
            padding: 15px;
            border-radius: 6px;
            margin-bottom: 20px;
            border-left: 3px solid #667eea;
        }
        
        .bookmark-info a {
            color: #667eea;
            text-decoration: none;
            word-break: break-all;
        }
        
        .error { color: #ff6b6b; }
        .success { color: #51cf66; }
        .warning { color: #ffa500; }

        .error-log {
            background: #1a1a1a;
            padding: 20px;
            border-radius: 8px;
            margin-top: 20px;
            border-left: 3px solid #ff6b6b;
            font-family: monospace;
            font-size: 12px;
            line-height: 1.6;
            display: none;
        }

        .error-log.has-errors {
            display: block;
        }

        .error-entry {
            padding: 8px;
            margin: 5px 0;
            background: rgba(255, 107, 107, 0.1);
            border-radius: 4px;
        }

        /* Animations for Notifications */
        @keyframes slideIn {
            from { transform: translateX(100%); opacity: 0; }
            to { transform: translateX(0); opacity: 1; }
        }
        @keyframes slideOut {
            from { transform: translateX(0); opacity: 1; }
            to { transform: translateX(100%); opacity: 0; }
        }
    </style>
</head>
<body>
    <h1>🎵 YT Mixer - Audio Playlist Mixer</h1>
    
    <!-- Setup Form (shown when no session) -->
    <div id="setup-form" class="setup-form">
        <h2>Create Your Mix</h2>
        <p style="color: #aaa; margin-bottom: 20px;">
            Enter two YouTube playlist IDs or full URLs to create your custom mix.
        </p>
        
        <div class="form-group">
            <label>🎵 Music Playlist ID or URL</label>
            <input type="text" id="music-input" placeholder="https://www.youtube.com/playlist?list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf or just the ID">
            <small style="color: #777;">Paste full YouTube playlist URL or just the playlist ID</small>
        </div>

        <div class="form-group">
            <label>🎙️ Speech/Podcast Playlist ID or URL</label>
            <input type="text" id="speech-input" placeholder="https://www.youtube.com/playlist?list=PLrAXtmErZgOdP_8GztsuKxGNuQ9Q1jCMD or just the ID">
            <small style="color: #777;">Paste full YouTube playlist URL or just the playlist ID</small>
        </div>
        
        <button class="btn" onclick="createSession()">🚀 Create Mix</button>
    </div>
    
    <!-- Player Section (shown when session exists) -->
    <div id="player-section" class="player-section">
        <div id="bookmark-info" class="bookmark-info"></div>
        
        <button class="big-play-btn" onclick="togglePlay()">▶</button>
        
        <audio id="player" controls></audio>
        
        <div class="controls">
            <button onclick="loadChunk()">🔄 Load Chunk</button>
            <button onclick="nextChunk()">⏭️ Next Chunk</button>
            <button onclick="updateStatus()">📊 Refresh Status</button>
            <button onclick="showLogs()">📋 View Logs</button>
        </div>
        
        <div class="status">
            <h3>Status</h3>
            <div id="status-content">Initializing...</div>
        </div>

        <div id="error-log" class="error-log">
            <h3>⚠️ Recent Errors</h3>
            <div id="error-content"></div>
        </div>
    </div>
        <div id="logModal" style="display:none; position:fixed; z-index:1000; left:0; top:0; width:100%; height:100%; overflow:auto; background-color:rgba(0,0,0,0.7);">
    <div style="background-color:#1e1e1e; color:#d4d4d4; margin:5% auto; padding:20px; border:1px solid #888; width:80%; height:80%; display:flex; flex-direction:column;">
        <div style="display:flex; justify-content:space-between; align-items:center;">
        <h2 style="margin:0;">🔴 Live Logs</h2>
        <button onclick="closeLogView()" style="font-size:24px; background:none; border:none; color:white; cursor:pointer;">&times;</button>
        </div>
        <pre id="logContent" style="flex-grow:1; overflow-y:scroll; background-color:#111; padding:10px; border-radius:5px; margin-top:10px; font-family:monospace; white-space:pre-wrap;"></pre>
    </div>
    </div>


    <script>
        // =========================================================
        // REAL-TIME MIXING MONITOR
        // =========================================================
        
        class MixingProgressMonitor {
            constructor() {
                this.progressContainer = null;
                this.pollInterval = null;
                this.init();
            }

            init() {
                this.createProgressUI();
                this.startPolling();
            }

            createProgressUI() {
                if (document.getElementById('mixing-progress')) {
                    this.progressContainer = document.getElementById('mixing-progress');
                    return;
                }

                const container = document.createElement('div');
                container.id = 'mixing-progress';
                container.style.cssText = `
                    position: fixed;
                    bottom: 80px;
                    right: 20px;
                    background: rgba(0, 0, 0, 0.9);
                    color: #fff;
                    padding: 15px;
                    border-radius: 8px;
                    max-width: 350px;
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
                    font-size: 13px;
                    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
                    z-index: 1000;
                    display: none;
                `;
                
                document.body.appendChild(container);
                this.progressContainer = container;
            }

            startPolling() {
                this.pollInterval = setInterval(() => {
                    this.fetchProgress();
                }, 2000);
                this.fetchProgress();
            }

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

            async fetchProgress() {
                try {
                    const response = await fetch('/api/status');
                    if (!response.ok) return;
                    
                    const status = await response.json();
                    this.updateUI(status);
                    this.updateErrors(status);
                } catch (error) {
                    console.error('Progress fetch error:', error);
                }
            }

            updateErrors(status) {
                const errorLog = document.getElementById('error-log');
                const errorContent = document.getElementById('error-content');
                
                if (status.errors && status.errors.length > 0) {
                    errorLog.classList.add('has-errors');
                    errorContent.innerHTML = status.errors.map(err => 
                        `<div class="error-entry"><span style="opacity:0.6">[${err.time}]</span> ${err.message}</div>`
                    ).join('');
                } else {
                    errorLog.classList.remove('has-errors');
                }
            }

            updateUI(status) {
                if (!status.mix_progress || Object.keys(status.mix_progress).length === 0) {
                    this.progressContainer.style.display = 'none';
                    return;
                }

                this.progressContainer.style.display = 'block';

                let html = '<div style="margin-bottom: 10px; font-weight: 600; font-size: 14px;">';
                html += '🎵 Mixing Progress</div>';

                const qualityBadges = {
                    'immediate': '<span style="background:#f59e0b;padding:2px 6px;border-radius:3px;font-size:11px;">⚡ IMMEDIATE</span>',
                    'quick': '<span style="background:#3b82f6;padding:2px 6px;border-radius:3px;font-size:11px;">📊 QUICK</span>',
                    'final': '<span style="background:#10b981;padding:2px 6px;border-radius:3px;font-size:11px;">✨ FINAL</span>'
                };
                
                const qualityBadge = qualityBadges[status.current_chunk_quality] || 
                    '<span style="background:#6b7280;padding:2px 6px;border-radius:3px;font-size:11px;">⏳ PREPARING</span>';
                
                html += `<div style="margin-bottom: 12px; opacity: 0.8;">
                    Playing: Chunk ${status.chunk_index} ${qualityBadge}
                </div>`;
                
                // Show LUFS queue status
                if (status.lufs_in_progress && status.lufs_in_progress > 0) {
                    html += `<div style="margin-bottom: 12px; padding: 8px; background: rgba(255,165,0,0.2); border-radius: 4px; font-size: 11px;">
                        🔥 LUFS Processing: ${status.lufs_in_progress} chunk(s) - Chunks: ${(status.lufs_chunks || []).join(', ')}
                    </div>`;
                }

                const chunks = Object.entries(status.mix_progress).sort((a, b) => b[0] - a[0]);
                
                for (const [chunkIdx, progress] of chunks) {
                    const stageName = this.getStageName(progress.stage);
                    const percent = progress.percent || 0;
                    const isActive = progress.stage && progress.stage !== 'complete';
                    
                    if (!isActive) continue;
                    
                    // Highlight if this chunk is doing LUFS
                    const isLufs = progress.stage === 'final_mix';
                    const bgColor = isLufs ? 'rgba(255,165,0,0.15)' : 'rgba(255,255,255,0.05)';
                    const chunkLabel = isLufs ? `Chunk ${chunkIdx} 🔥` : `Chunk ${chunkIdx}`;

                    html += `
                        <div style="margin-bottom: 8px; padding: 8px; background: ${bgColor}; border-radius: 4px;">
                            <div style="display: flex; justify-content: space-between; margin-bottom: 4px;">
                                <span style="font-weight: ${isLufs ? 'bold' : 'normal'};">${chunkLabel}</span>
                                <span style="opacity: 0.7;">${percent}%</span>
                            </div>
                            <div style="font-size: 11px; opacity: 0.8; margin-bottom: 4px;">${stageName}</div>
                            <div style="background: rgba(255,255,255,0.1); height: 4px; border-radius: 2px; overflow: hidden;">
                                <div style="background: ${this.getStageColor(progress.stage)}; height: 100%; width: ${percent}%; transition: width 0.3s;"></div>
                            </div>
                        </div>
                    `;
                }

                html += `
                    <div style="margin-top: 12px; padding-top: 12px; border-top: 1px solid rgba(255,255,255,0.1); font-size: 11px; opacity: 0.6;">
                        Preloaded: ${status.preloaded_count} chunks | 
                        Music: ${status.music_queue_size} | 
                        Speech: ${status.speech_queue_size}
                    </div>
                `;

                this.progressContainer.innerHTML = html;
            }

            getStageName(stage) {
                const stages = {
                    'collecting': '📥 Downloading tracks from playlists',
                    'concatenating': '🔗 Combining audio files',
                    'immediate_mix': '⚡ Generating IMMEDIATE mix (no normalization)',
                    'quick_mix': '📊 Normalizing tracks separately (fast)',
                    'final_mix': '✨ Mastering with LUFS (professional quality)'
                };
                return stages[stage] || stage;
            }

            getStageColor(stage) {
                const colors = {
                    'collecting': '#3b82f6',
                    'concatenating': '#8b5cf6',
                    'immediate_mix': '#f59e0b',
                    'quick_mix': '#3b82f6',
                    'final_mix': '#10b981'
                };
                return colors[stage] || '#6b7280';
            }

            destroy() {
                this.stopPolling();
                if (this.progressContainer) {
                    this.progressContainer.remove();
                }
            }
        }

        // =========================================================
        // MAIN APPLICATION LOGIC
        // =========================================================
        
        const urlParams = new URLSearchParams(window.location.search);
        const sessionID = urlParams.get('sid');
        
        const audio = document.getElementById('player');
        const bigPlayBtn = document.querySelector('.big-play-btn');
        const statusContent = document.getElementById('status-content');
        
        let isPlaying = false;
        let currentChunkIndex = 0;
        let savedPosition = 0;
        let positionSaveInterval = null;
        let isInitialLoad = true;
        document.addEventListener('DOMContentLoaded', () => {
            if (sessionID) {
                window.mixingMonitor = new MixingProgressMonitor();
            }
        });
        // Save playback position every 5 seconds
        function startPositionSaving() {
            if (positionSaveInterval) clearInterval(positionSaveInterval);
            
            positionSaveInterval = setInterval(() => {
                if (!audio.paused && !audio.ended && sessionID) {
                    fetch('/api/playback/position', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            session_id: sessionID,
                            chunk_index: currentChunkIndex,
                            position: audio.currentTime
                        })
                    }).catch(e => console.error('Position save failed:', e));
                }
            }, 5000);
        }

        // Load saved position from server
        async function loadSavedPosition() {
            if (!sessionID) return;
            
            try {
                const resp = await fetch(`/api/playback/position/${sessionID}`);
                const data = await resp.json();
                
                if (data.chunk_index !== undefined) {
                    currentChunkIndex = data.chunk_index;
                    savedPosition = data.position_seconds || 0;
                    console.log(`Restored position: chunk ${currentChunkIndex}, time ${savedPosition}s`);
                }
            } catch (e) {
                console.error('Failed to load saved position:', e);
            }
        }
        window.addEventListener('beforeunload', () => {
            if (window.mixingMonitor) {
                window.mixingMonitor.destroy();
            }
        });
        
        if (sessionID) {
            document.getElementById('setup-form').style.display = 'none';
            document.getElementById('player-section').classList.add('active');
            
            const bookmarkDiv = document.getElementById('bookmark-info');
            bookmarkDiv.innerHTML = `
                <strong>🔗 Bookmark this URL to return to your mix:</strong><br>
                <a href="/?sid=${sessionID}">${window.location.origin}/?sid=${sessionID}</a>
            `;
            
            initializePlayer();
        } else {
            document.getElementById('setup-form').style.display = 'block';
            document.getElementById('player-section').classList.remove('active');
        }
        
        function createSession() {
            const musicId = document.getElementById('music-input').value.trim();
            const speechId = document.getElementById('speech-input').value.trim();
            
            if (!musicId || !speechId) {
                alert('Please enter both playlist IDs');
                return;
            }
            
            window.location.href = `/?m=${encodeURIComponent(musicId)}&s=${encodeURIComponent(speechId)}`;
        }
        
        async function initializePlayer() {
            await loadSavedPosition();
            startPositionSaving();
            updateStatus();
            setInterval(updateStatus, 10000);
        }
        
        function togglePlay() {
            if (!audio.src || audio.src === '') {
                loadChunk();
                return;
            }
            
            if (isPlaying) {
                audio.pause();
                bigPlayBtn.textContent = '▶';
                isPlaying = false;
            } else {
                audio.play().then(() => {
                    bigPlayBtn.textContent = '⏸';
                    isPlaying = true;
                }).catch(err => {
                    console.error("Error playing audio:", err);
                    statusContent.innerHTML = `<span class="error">Error: ${err.message}</span>`;
                });
            }
        }
        
        audio.onplay = () => {
            bigPlayBtn.textContent = '⏸';
            isPlaying = true;
        };
        
        audio.onpause = () => {
            bigPlayBtn.textContent = '▶';
            isPlaying = false;
        };
        
        function loadChunk() {
            statusContent.innerHTML = '<span class="success">Loading audio...</span>';
            
            audio.src = `/stream?t=${Date.now()}`;

            // Restore saved position on first load
            if (isInitialLoad && savedPosition > 0) {
                audio.addEventListener('loadedmetadata', function restorePos() {
                    audio.currentTime = savedPosition;
                    audio.removeEventListener('loadedmetadata', restorePos);
                    isInitialLoad = false;
                });
            }

            audio.load();
            
            audio.oncanplaythrough = () => {
                audio.play().then(() => {
                    bigPlayBtn.textContent = '⏸';
                    isPlaying = true;
                    updateStatus();
                }).catch(err => {
                    console.error("Error playing audio:", err);
                    statusContent.innerHTML = `<span class="error">Error playing: ${err.message}</span>`;
                });
            };
            
            audio.onerror = () => {
                statusContent.innerHTML = '<span class="warning">Waiting for audio (First mix takes 10-30s)...</span>';
            };
        }
        
        function nextChunk() {
            statusContent.innerHTML = '<span class="success">Switching to next chunk...</span>';
            
            fetch('/next')
                .then(r => r.json())
                .then(data => {
                    if (data.success) {
                    currentChunkIndex = data.chunk_index;
                    savedPosition = 0; // Reset for new chunk
                    setTimeout(() => {
                        loadChunk();
                    }, 500);
                    } else {
                        statusContent.innerHTML = `<span class="error">No next chunk available: ${data.error || 'Still preparing'}</span>`;
                    }
                })
                .catch(err => {
                    console.error("Error switching chunk:", err);
                    statusContent.innerHTML = `<span class="error">Error: ${err.message}</span>`;
                });
        }
        
        function updateStatus() {
            fetch('/api/status')
                .then(r => r.json())
                .then(data => {
                    if (data.error) {
                        statusContent.innerHTML = `<span class="error">${data.error}</span>`;
                        return;
                    }
                    
                    const chunkName = data.current_chunk ? 
                        data.current_chunk.split('/').pop() : 'None (preparing...)';
                    currentChunkIndex = data.chunk_index || 0;
                    const qualityMap = {
                        'immediate': '⚡ IMMEDIATE (Raw mix - upgrading...)',
                        'quick': '📊 QUICK (Normalized)',
                        'final': '✨ FINAL (LUFS mastered)',
                        'none': '⏳ Preparing...'
                    };
                    const qualityText = qualityMap[data.current_chunk_quality] || '';
                    
                    let lufsInfo = '';
                    if (data.lufs_in_progress && data.lufs_in_progress > 0) {
                        lufsInfo = `<br><strong style="color:#ffa500;">🔥 LUFS Active:</strong> ${data.lufs_in_progress} chunk(s) - ${(data.lufs_chunks || []).join(', ')}`;
                    }
                    
                    statusContent.innerHTML = `
                        <strong>Session:</strong> ${data.session_id || sessionID}<br>
                        <strong>Current Chunk:</strong> ${chunkName}<br>
                        <strong>Quality:</strong> ${qualityText}<br>
                        <strong>Chunk Index:</strong> ${data.chunk_index || 0}<br>
                        <strong>Ready Chunks:</strong> ${data.preloaded_count || 0}<br>
                        <strong>Queue Status:</strong> Music: ${data.music_queue_size || 0}, Speech: ${data.speech_queue_size || 0}${lufsInfo}
                    `;
                })
                .catch(err => {
                    console.error("Error fetching status:", err);
                    statusContent.innerHTML = `<span class="error">Status unavailable</span>`;
                });
        }

        function showLogs() {
            // Use the existing viewLogs() function which shows modal
            viewLogs();
        }

        function viewLogs() {
            const modal = document.getElementById('logModal');
            const content = document.getElementById('logContent');
            
            modal.style.display = 'block';
            content.innerHTML = 'Loading logs...\n';

            // Simple fetch, no SSE
            fetch('/api/logs')
                .then(r => r.json())
                .then(data => {
                    if (data.logs && data.logs.length > 0) {
                        content.innerHTML = data.logs.join('');
                        // Auto-scroll to bottom
                        content.scrollTop = content.scrollHeight;
                    } else {
                        content.innerHTML = 'No logs available\n';
                    }
                })
                .catch(err => {
                    content.innerHTML = 'Error loading logs: ' + err.message + '\n';
                });
        }

        function closeLogView() {
            const modal = document.getElementById('logModal');
            modal.style.display = 'none';
        }
        
        audio.onended = () => {
            console.log("Audio ended, advancing to next chunk");
            nextChunk();
        };

        window.addEventListener('chunk-upgraded', (event) => {
            const notification = document.createElement('div');
            notification.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                background: #10b981;
                color: white;
                padding: 12px 20px;
                border-radius: 6px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                z-index: 9999;
                animation: slideIn 0.3s ease-out;
            `;
            notification.textContent = '✨ Audio quality upgraded to FINAL mix!';
            document.body.appendChild(notification);
            
            setTimeout(() => {
                notification.style.animation = 'slideOut 0.3s ease-out';
                setTimeout(() => notification.remove(), 300);
            }, 3000);
        });
    </script>
</body>
</html>