// Player Dashboard JavaScript

let selectedMatch = null;
let selectedOutcome = null;
let selectedOdds = null;
let hlsPlayer = null;

// HLS Stream configuration - will be set dynamically from server config
let HLS_STREAM_URL = '/hls/stream.m3u8';  // Default, will be updated from config
let streamingConfig = null;  // Store full streaming config
const HLS_RECONNECT_DELAY = 1000;  // Initial reconnect delay in ms
const HLS_MAX_RECONNECT_DELAY = 30000;  // Max reconnect delay in ms
const HLS_MAX_RECONNECT_ATTEMPTS = 10;  // Max reconnect attempts before showing error

let reconnectAttempts = 0;
let totalReconnectAttempts = 0;  // Total reconnection attempts for debug display
let reconnectTimeout = null;
let isStreamActive = false;

// Overlay controller reference
let overlayController = null;

// Debug mode - enabled via URL parameter debug=ENABLE
let debugMode = false;
let debugOverlay = null;
let debugUpdateInterval = null;

// Check for debug mode in URL
function checkDebugMode() {
    const urlParams = new URLSearchParams(window.location.search);
    const debugParam = urlParams.get('debug');
    debugMode = (debugParam === 'ENABLE');
    
    if (debugMode) {
        console.log('%c[DEBUG MODE ENABLED]', 'color: #00ff00; font-weight: bold; font-size: 14px;');
        console.log('[DEBUG] Debug mode activated via URL parameter debug=ENABLE');
        createDebugOverlay();
    }
    
    return debugMode;
}

// Debug log function - only logs when debug mode is enabled
function debugLog(category, message, data = null) {
    if (!debugMode) return;
    
    const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
    const prefix = `[DEBUG ${timestamp}]`;
    
    if (data) {
        console.log(`%c${prefix} [${category}]`, 'color: #00ff00;', message, data);
    } else {
        console.log(`%c${prefix} [${category}]`, 'color: #00ff00;', message);
    }
}

// Create debug overlay
function createDebugOverlay() {
    // Create debug overlay container
    debugOverlay = document.createElement('div');
    debugOverlay.id = 'debug-overlay';
    debugOverlay.innerHTML = `
        <style>
            #debug-overlay {
                position: fixed;
                top: 10px;
                right: 10px;
                background: rgba(0, 0, 0, 0.85);
                color: #00ff00;
                font-family: 'Courier New', monospace;
                font-size: 11px;
                padding: 10px;
                border-radius: 8px;
                z-index: 99999;
                min-width: 280px;
                max-width: 350px;
                border: 1px solid #00ff00;
                box-shadow: 0 0 10px rgba(0, 255, 0, 0.3);
            }
            #debug-overlay .debug-header {
                font-weight: bold;
                font-size: 12px;
                margin-bottom: 8px;
                padding-bottom: 5px;
                border-bottom: 1px solid #00ff00;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }
            #debug-overlay .debug-section {
                margin-bottom: 8px;
            }
            #debug-overlay .debug-label {
                color: #888;
            }
            #debug-overlay .debug-value {
                color: #00ff00;
                font-weight: bold;
            }
            #debug-overlay .debug-warning {
                color: #ffaa00;
            }
            #debug-overlay .debug-error {
                color: #ff4444;
            }
            #debug-overlay .debug-bar {
                height: 4px;
                background: #333;
                border-radius: 2px;
                margin-top: 2px;
            }
            #debug-overlay .debug-bar-fill {
                height: 100%;
                background: #00ff00;
                border-radius: 2px;
                transition: width 0.1s;
            }
            #debug-overlay .debug-close {
                cursor: pointer;
                padding: 2px 6px;
                border: 1px solid #00ff00;
                border-radius: 3px;
            }
            #debug-overlay .debug-close:hover {
                background: #00ff00;
                color: #000;
            }
        </style>
        <div class="debug-header">
            <span>🔧 DEBUG MODE</span>
            <span class="debug-close" onclick="toggleDebugOverlay()">×</span>
        </div>
        <div class="debug-section">
            <span class="debug-label">Video Time:</span>
            <span class="debug-value" id="debug-video-time">--:--:--</span>
            <span class="debug-label"> / </span>
            <span class="debug-value" id="debug-video-duration">--:--:--</span>
        </div>
        <div class="debug-section">
            <span class="debug-label">Buffer:</span>
            <span class="debug-value" id="debug-buffer">0.0s</span>
            <div class="debug-bar"><div class="debug-bar-fill" id="debug-buffer-bar" style="width: 0%"></div></div>
        </div>
        <div class="debug-section">
            <span class="debug-label">Stream Status:</span>
            <span class="debug-value" id="debug-stream-status">offline</span>
        </div>
        <div class="debug-section">
            <span class="debug-label">HLS State:</span>
            <span class="debug-value" id="debug-hls-state">idle</span>
        </div>
        <div class="debug-section">
            <span class="debug-label">Reconnects:</span>
            <span class="debug-value" id="debug-reconnects">0</span>
        </div>
        <div class="debug-section">
            <span class="debug-label">Frame Drops:</span>
            <span class="debug-value" id="debug-drops">0</span>
        </div>
        <div class="debug-section">
            <span class="debug-label">Bitrate:</span>
            <span class="debug-value" id="debug-bitrate">-- kbps</span>
        </div>
        <div class="debug-section">
            <span class="debug-label">Resolution:</span>
            <span class="debug-value" id="debug-resolution">-- x --</span>
        </div>
        <div class="debug-section">
            <span class="debug-label">Last Error:</span>
            <span class="debug-value" id="debug-last-error">none</span>
        </div>
    `;
    document.body.appendChild(debugOverlay);
    
    // Start debug update interval
    debugUpdateInterval = setInterval(updateDebugOverlay, 100);
    
    debugLog('INIT', 'Debug overlay created');
}

// Toggle debug overlay visibility
function toggleDebugOverlay() {
    if (debugOverlay) {
        debugOverlay.style.display = debugOverlay.style.display === 'none' ? 'block' : 'none';
    }
}

// Update debug overlay with current stats
function updateDebugOverlay() {
    if (!debugMode || !debugOverlay) return;
    
    const video = document.getElementById('hls-player');
    if (!video) return;
    
    // Video time
    const currentTime = video.currentTime || 0;
    const duration = video.duration || 0;
    document.getElementById('debug-video-time').textContent = formatTime(currentTime);
    document.getElementById('debug-video-duration').textContent = isFinite(duration) ? formatTime(duration) : 'LIVE';
    
    // Buffer info
    if (video.buffered && video.buffered.length > 0) {
        const bufferEnd = video.buffered.end(video.buffered.length - 1);
        const bufferLength = bufferEnd - currentTime;
        document.getElementById('debug-buffer').textContent = `${bufferLength.toFixed(1)}s`;
        
        // Buffer bar (max 60 seconds)
        const bufferPercent = Math.min((bufferLength / 60) * 100, 100);
        document.getElementById('debug-buffer-bar').style.width = `${bufferPercent}%`;
        
        // Color based on buffer health
        const bufferElement = document.getElementById('debug-buffer');
        if (bufferLength < 2) {
            bufferElement.className = 'debug-error';
        } else if (bufferLength < 5) {
            bufferElement.className = 'debug-warning';
        } else {
            bufferElement.className = 'debug-value';
        }
    } else {
        document.getElementById('debug-buffer').textContent = '0.0s';
        document.getElementById('debug-buffer-bar').style.width = '0%';
    }
    
    // Stream status
    document.getElementById('debug-stream-status').textContent = isStreamActive ? 'LIVE' : 'offline';
    
    // HLS state - HLS.js uses different state tracking
    if (hlsPlayer) {
        // Get HLS.js state - it doesn't have a simple 'state' property
        let hlsState = 'unknown';
        if (hlsPlayer.autoLevelEnabled !== undefined) {
            if (isStreamActive) {
                hlsState = 'playing';
            } else {
                hlsState = 'stopped';
            }
        }
        
        // Check for errors
        if (hlsPlayer.error) {
            hlsState = 'error';
        }
        
        document.getElementById('debug-hls-state').textContent = hlsState;
        
        // Bitrate and resolution - HLS.js uses 'levels' array
        let bitrateFound = false;
        let resolutionFound = false;
        
        if (hlsPlayer.levels && hlsPlayer.levels.length > 0) {
            // Get current level or use auto
            const currentLevel = hlsPlayer.currentLevel;
            let level = null;
            let levelName = 'auto';
            
            if (currentLevel >= 0 && currentLevel < hlsPlayer.levels.length) {
                level = hlsPlayer.levels[currentLevel];
                // Try to get level name from HLS.js
                levelName = level.name || `Level ${currentLevel}`;
            } else if (hlsPlayer.levels.length > 0) {
                // Auto mode - show currently playing level
                level = hlsPlayer.levels[hlsPlayer.levels.length - 1];
                levelName = 'auto';
            }
            
            if (level) {
                const bitrate = level.bitrate || 0;
                const width = level.width || 0;
                const height = level.height || 0;
                
                if (bitrate > 0) {
                    // Show bitrate with quality name if available
                    const qualityLabel = getQualityLabel(bitrate, height);
                    document.getElementById('debug-bitrate').textContent = `${Math.round(bitrate / 1000)} kbps (${qualityLabel})`;
                    bitrateFound = true;
                }
                if (width && height) {
                    document.getElementById('debug-resolution').textContent = `${width} x ${height}`;
                    resolutionFound = true;
                }
            }
            
            // Log available quality levels for debugging
            if (hlsPlayer.levels.length > 1) {
                console.log(`HLS: ${hlsPlayer.levels.length} quality levels available, current: ${currentLevel >= 0 ? currentLevel : 'auto'}`);
            }
        }
        
        // Fallback: Get resolution from video element
        if (!resolutionFound && video.videoWidth && video.videoHeight) {
            document.getElementById('debug-resolution').textContent = `${video.videoWidth} x ${video.videoHeight}`;
            resolutionFound = true;
        }
        
        // Fallback: Estimate bitrate from HLS.js stats or use configured bitrate
        if (!bitrateFound) {
            // Try to get bitrate from HLS.js frag loader stats
            if (hlsPlayer.stats && hlsPlayer.stats.bandwidth) {
                const bandwidth = hlsPlayer.stats.bandwidth;
                document.getElementById('debug-bitrate').textContent = `${Math.round(bandwidth / 1000)} kbps`;
                bitrateFound = true;
            } else if (hlsPlayer.bandwidthEstimate) {
                // HLS.js bandwidth estimate
                document.getElementById('debug-bitrate').textContent = `${Math.round(hlsPlayer.bandwidthEstimate / 1000)} kbps`;
                bitrateFound = true;
            } else {
                // Use configured bitrate as fallback (from streaming config)
                // This is set in the HLS config: video_bitrate: "1500k"
                document.getElementById('debug-bitrate').textContent = '1500 kbps';
                bitrateFound = true;
            }
        }
        
        // Final fallback if nothing found
        if (!bitrateFound) {
            document.getElementById('debug-bitrate').textContent = '-- kbps';
        }
        if (!resolutionFound) {
            document.getElementById('debug-resolution').textContent = '-- x --';
        }
    } else if (usingNativeHls) {
        // Native HLS (iOS, Safari) - show state based on video element
        let hlsState = 'not loaded';
        
        if (video.src && video.src.includes('.m3u8')) {
            if (isStreamActive) {
                hlsState = 'playing (native)';
            } else if (video.error) {
                hlsState = 'error';
            } else if (video.readyState >= 1) {
                hlsState = 'loaded (native)';
            } else {
                hlsState = 'loading (native)';
            }
        }
        
        document.getElementById('debug-hls-state').textContent = hlsState;
        
        // Get resolution from video element for native HLS
        if (video.videoWidth && video.videoHeight) {
            document.getElementById('debug-resolution').textContent = `${video.videoWidth} x ${video.videoHeight}`;
        } else {
            document.getElementById('debug-resolution').textContent = '-- x --';
        }
        
        // Native HLS doesn't expose bitrate, use configured value
        document.getElementById('debug-bitrate').textContent = '1500 kbps';
    } else {
        document.getElementById('debug-hls-state').textContent = 'not loaded';
        document.getElementById('debug-bitrate').textContent = '-- kbps';
        document.getElementById('debug-resolution').textContent = '-- x --';
    }
    
    // Reconnect attempts
    document.getElementById('debug-reconnects').textContent = totalReconnectAttempts;
    
    // Frame drops (from video element)
    if (video.getVideoPlaybackQuality) {
        const quality = video.getVideoPlaybackQuality();
        document.getElementById('debug-drops').textContent = quality.droppedVideoFrames || 0;
    }
}

// Format time as HH:MM:SS
function formatTime(seconds) {
    const h = Math.floor(seconds / 3600);
    const m = Math.floor((seconds % 3600) / 60);
    const s = Math.floor(seconds % 60);
    return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
}

// Update last error in debug overlay
function setDebugError(error) {
    if (!debugMode) return;
    const errorElement = document.getElementById('debug-last-error');
    if (errorElement) {
        errorElement.textContent = error;
        errorElement.className = 'debug-error';
    }
}

// Load streaming configuration from server
async function loadStreamingConfig() {
    try {
        // This is a public endpoint - no authentication required
        const response = await fetch('/api/streaming/config');
        
        if (response.ok) {
            const data = await response.json();
            streamingConfig = data;
            
            console.log('Streaming config response:', data);
            
            // Use the pre-built HLS URL from the server (preferred)
            if (data.success && data.streaming && data.streaming.hls_url) {
                HLS_STREAM_URL = data.streaming.hls_url;
                console.log('Using server-provided HLS URL:', HLS_STREAM_URL);
                debugLog('CONFIG', 'Using server-provided HLS URL: ' + HLS_STREAM_URL);
            } else if (data.success && data.streaming && data.streaming.base_url) {
                // Build URL from base_url
                HLS_STREAM_URL = `${data.streaming.base_url}/hls/stream.m3u8`;
                console.log('Using base_url to build HLS URL:', HLS_STREAM_URL);
                debugLog('CONFIG', 'Using base_url to build HLS URL: ' + HLS_STREAM_URL);
            } else {
                // Fallback to relative URL (same host as web dashboard)
                HLS_STREAM_URL = '/hls/stream.m3u8';
                console.log('Using fallback stream URL:', HLS_STREAM_URL);
                debugLog('CONFIG', 'Using fallback stream URL: ' + HLS_STREAM_URL);
            }
            
            // Log the video hostname for debugging
            if (data.streaming && data.streaming.video_hostname) {
                console.log('Video hostname configured:', data.streaming.video_hostname);
                debugLog('CONFIG', 'Video hostname: ' + data.streaming.video_hostname);
            }
        } else {
            console.warn('Failed to load streaming config, using defaults');
            HLS_STREAM_URL = '/hls/stream.m3u8';
        }
    } catch (error) {
        console.warn('Could not load streaming config, using defaults:', error);
        // Keep default URL
        HLS_STREAM_URL = '/hls/stream.m3u8';
    }
    
    return HLS_STREAM_URL;
}

// Check authentication on page load
document.addEventListener('DOMContentLoaded', async () => {
    // Check for debug mode first
    checkDebugMode();
    
    checkAuthStatus();
    
    // Only load data if we have a valid token
    if (authToken) {
        // Check role-based access - only players can access this page
        if (currentUser && currentUser.role === 'broker') {
            console.log('Broker user attempted to access player area, redirecting to broker dashboard');
            showNotification('Brokers do not have access to the player area.', 'error');
            window.location.href = 'broker.html';
            return;
        }
        
        // Load streaming config first to get the correct video URL
        await loadStreamingConfig();
        
        loadPlayerData();
        loadMatches();
        initializeAndStartStream();
        await initializeOverlayController();
    } else {
        // Redirect to login if no token
        window.location.href = 'index.html';
    }
});

// Initialize overlay controller for web player
async function initializeOverlayController() {
    try {
        // Check if overlay controller script is loaded
        if (typeof WebOverlayController === 'undefined') {
            console.warn('WebOverlayController not loaded - overlay templates disabled');
            return;
        }
        
        // Create overlay controller instance
        overlayController = new WebOverlayController({
            apiBaseUrl: '/api/overlay',  // API endpoint for overlay data
            overlayContainerId: 'overlay-container',
            videoElementId: 'hls-player',
            pollInterval: 1000,  // Poll every second for overlay data
            debug: false
        });
        
        // Set up event listeners
        overlayController.on('templateLoaded', (templateName) => {
            console.log('Overlay template loaded:', templateName);
        });
        
        overlayController.on('dataUpdated', (data) => {
            console.log('Overlay data updated:', data);
        });
        
        overlayController.on('error', (error) => {
            console.error('Overlay controller error:', error);
        });
        
        // Initialize the controller
        await overlayController.initialize();
        console.log('Overlay controller initialized successfully');
        
    } catch (error) {
        console.error('Failed to initialize overlay controller:', error);
    }
}

// Load player-specific data
async function loadPlayerData() {
    try {
        // Load balance
        const balanceData = await apiRequest('/player/balance');
        const balance = parseFloat(balanceData.balance) || 0;
        const available = parseFloat(balanceData.available) || 0;
        const pending = parseFloat(balanceData.pending) || 0;
        
        document.getElementById('user-balance').textContent = `Balance: $${balance.toFixed(2)}`;
        document.getElementById('account-balance').textContent = `$${balance.toFixed(2)}`;
        document.getElementById('available-balance').textContent = `$${available.toFixed(2)}`;
        document.getElementById('pending-bets').textContent = `$${pending.toFixed(2)}`;
        
        // Load recent bets
        const betsData = await apiRequest('/player/bets?limit=5');
        displayRecentBets(betsData.bets || []);
        
        // Load statistics
        const statsData = await apiRequest('/player/statistics');
        document.getElementById('total-bets').textContent = statsData.total_bets || 0;
        document.getElementById('bets-won').textContent = statsData.bets_won || 0;
        document.getElementById('bets-lost').textContent = statsData.bets_lost || 0;
        document.getElementById('win-rate').textContent = `${(statsData.win_rate || 0).toFixed(1)}%`;
        
        const profitLoss = statsData.profit_loss || 0;
        const profitLossElement = document.getElementById('profit-loss');
        profitLossElement.textContent = `$${profitLoss.toFixed(2)}`;
        profitLossElement.style.color = profitLoss >= 0 ? 'var(--success-color)' : 'var(--error-color)';
        
        // Update user name and avatar
        if (currentUser) {
            const displayName = currentUser.real_name || currentUser.username || 'Player';
            document.getElementById('user-name').textContent = displayName;
            
            // Update avatar with Gravatar
            const avatarElement = document.getElementById('user-avatar');
            if (avatarElement) {
                if (currentUser.avatar_url) {
                    avatarElement.src = currentUser.avatar_url;
                } else if (currentUser.email) {
                    const emailHash = md5Hash(currentUser.email.toLowerCase().trim());
                    avatarElement.src = `https://www.gravatar.com/avatar/${emailHash}?s=32&d=identicon`;
                }
            }
        }
    } catch (error) {
        console.error('Error loading player data:', error);
        showNotification('Failed to load player data. Please refresh the page.', 'error');
    }
}

// Store matches data globally for odds access
let matchesCache = [];

// Load available matches
async function loadMatches() {
    try {
        const matchesData = await apiRequest('/player/matches?status=live,upcoming');
        const matchSelect = document.getElementById('match-select');
        
        matchSelect.innerHTML = '<option value="">Select a match</option>';
        matchesCache = matchesData.matches || [];
        
        matchesCache.forEach(match => {
            const option = document.createElement('option');
            option.value = match.id;
            option.textContent = `${match.fighter1 || match.home_team} vs ${match.fighter2 || match.away_team} - ${match.status}`;
            option.matchData = match;  // Store match data for odds access
            matchSelect.appendChild(option);
        });
        
        // Load upcoming matches section
        displayUpcomingMatches(matchesCache.filter(m => m.status === 'upcoming'));
        
        // Auto-select first live match if available
        const liveMatch = matchesCache.find(m => m.status === 'live');
        if (liveMatch) {
            matchSelect.value = liveMatch.id;
            loadMatchOdds();
            loadLiveStream(liveMatch.id);
        }
    } catch (error) {
        console.error('Error loading matches:', error);
        showNotification('Failed to load matches. Please try again.', 'error');
    }
}

// Load match odds
async function loadMatchOdds() {
    const matchId = document.getElementById('match-select').value;
    
    if (!matchId) {
        document.getElementById('betting-options').innerHTML = '<p>Please select a match to view betting options.</p>';
        return;
    }
    
    try {
        // Get odds from the matches data (already loaded)
        // The odds are included in the match data from /player/matches
        const matchSelect = document.getElementById('match-select');
        const selectedOption = matchSelect.options[matchSelect.selectedIndex];
        const matchData = selectedOption.matchData;
        
        if (matchData && matchData.odds) {
            // Convert odds object to outcomes array
            const outcomes = [
                { id: 'fighter1', name: matchData.fighter1 || 'Fighter 1', odds: matchData.odds.fighter1 || 1.0 },
                { id: 'fighter2', name: matchData.fighter2 || 'Fighter 2', odds: matchData.odds.fighter2 || 1.0 },
                { id: 'draw', name: 'Draw', odds: matchData.odds.draw || 3.0 }
            ];
            displayBettingOptions(outcomes);
            selectedMatch = matchId;
        } else {
            document.getElementById('betting-options').innerHTML = '<p>Odds not available for this match.</p>';
        }
    } catch (error) {
        console.error('Error loading match odds:', error);
        showNotification('Failed to load betting options. Please try again.', 'error');
    }
}

// Display betting options
function displayBettingOptions(outcomes) {
    const container = document.getElementById('betting-options');
    container.innerHTML = '';
    
    outcomes.forEach(outcome => {
        const option = document.createElement('div');
        option.className = 'betting-option';
        option.innerHTML = `
            <div class="odds">${outcome.odds.toFixed(2)}</div>
            <div class="label">${outcome.name}</div>
        `;
        option.addEventListener('click', () => selectOutcome(outcome, option));
        container.appendChild(option);
    });
}

// Select betting outcome
function selectOutcome(outcome, element) {
    // Remove previous selection
    document.querySelectorAll('.betting-option').forEach(opt => opt.classList.remove('selected'));
    
    // Add selection to clicked element
    element.classList.add('selected');
    
    selectedOutcome = outcome.id;
    selectedOdds = outcome.odds;
    
    // Update bet summary
    updateBetSummary();
}

// Update bet summary
function updateBetSummary() {
    const betAmount = parseFloat(document.getElementById('bet-amount').value) || 0;
    const summaryDiv = document.getElementById('bet-summary');
    
    if (selectedOutcome && betAmount > 0) {
        const potentialWin = betAmount * selectedOdds;
        
        document.getElementById('summary-outcome').textContent = selectedOutcome;
        document.getElementById('summary-odds').textContent = selectedOdds.toFixed(2);
        document.getElementById('summary-potential').textContent = `$${potentialWin.toFixed(2)}`;
        
        summaryDiv.style.display = 'block';
    } else {
        summaryDiv.style.display = 'none';
    }
}

// Place bet
async function placeBet() {
    const betAmount = parseFloat(document.getElementById('bet-amount').value);
    
    if (!selectedMatch || !selectedOutcome) {
        showNotification('Please select a match and outcome.', 'error');
        return;
    }
    
    if (!betAmount || betAmount <= 0) {
        showNotification('Please enter a valid bet amount.', 'error');
        return;
    }
    
    try {
        const response = await apiRequest('/player/bets', {
            method: 'POST',
            body: JSON.stringify({
                match_id: selectedMatch,
                outcome_id: selectedOutcome,
                amount: betAmount
            })
        });
        
        showNotification('Bet placed successfully!', 'success');
        
        // Reset form
        document.getElementById('bet-amount').value = '';
        document.getElementById('bet-summary').style.display = 'none';
        document.querySelectorAll('.betting-option').forEach(opt => opt.classList.remove('selected'));
        selectedOutcome = null;
        selectedOdds = null;
        
        // Reload player data
        loadPlayerData();
    } catch (error) {
        console.error('Error placing bet:', error);
        showNotification('Failed to place bet. Please try again.', 'error');
    }
}

// Detect mobile device
// Get quality label based on bitrate and resolution
function getQualityLabel(bitrate, height) {
    // Match our FFmpeg encoding profiles:
    // High: 1080p @ 10000kbps (10 Mbps)
    // Mid: 720p @ 5000kbps (5 Mbps)
    // Low: 480p @ 2000kbps (2 Mbps)
    if (height >= 1080 || bitrate >= 8000000) {
        return 'High';
    } else if (height >= 720 || bitrate >= 4000000) {
        return 'Medium';
    } else {
        return 'Low';
    }
}

function isMobileDevice() {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}

// Detect iOS device
let streamInitialized = false;  // Guard to prevent multiple initializations
let usingNativeHls = false;     // Track if using native HLS (for debug display)

function isIOS() {
    return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
}

// Initialize and start HLS stream with robust error handling
function initializeAndStartStream() {
    // Guard against multiple initializations
    if (streamInitialized) {
        console.log('Stream already initialized, skipping');
        return;
    }
    streamInitialized = true;
    
    const video = document.getElementById('hls-player');
    
    if (!video) {
        console.error('Video element not found');
        streamInitialized = false;
        return;
    }
    
    debugLog('HLS', 'Initializing HLS stream...');
    debugLog('HLS', 'Mobile device: ' + isMobileDevice());
    debugLog('HLS', 'iOS device: ' + isIOS());
    
    console.log('Initializing HLS stream...');
    console.log('Mobile device:', isMobileDevice());
    console.log('iOS device:', isIOS());
    
    // iOS devices should use native HLS for best compatibility
    if (isIOS() && video.canPlayType('application/vnd.apple.mpegurl')) {
        console.log('iOS detected - using native HLS support');
        debugLog('HLS', 'iOS detected - using native HLS support');
        usingNativeHls = true;
        initializeNativeHls(video);
        return;
    }
    
    // Check if HLS.js is supported
    if (Hls.isSupported()) {
        // On mobile, prefer native HLS if available (better battery/performance)
        if (isMobileDevice() && video.canPlayType('application/vnd.apple.mpegurl')) {
            console.log('Mobile device with native HLS - using native support');
            debugLog('HLS', 'Mobile device with native HLS - using native support');
            usingNativeHls = true;
            initializeNativeHls(video);
        } else {
            debugLog('HLS', 'Using HLS.js library');
            usingNativeHls = false;
            initializeHlsJs(video);
        }
    } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
        // Native HLS support (Safari, iOS)
        console.log('Native HLS support detected');
        debugLog('HLS', 'Native HLS support detected');
        usingNativeHls = true;
        initializeNativeHls(video);
    } else {
        console.error('HLS is not supported in this browser');
        debugLog('HLS', 'ERROR: HLS is not supported in this browser');
        setDebugError('HLS not supported');
        showNotification('Your browser does not support HLS video playback.', 'error');
        streamInitialized = false;
    }
}

// Initialize hls.js player with error recovery
function initializeHlsJs(video) {
    // Destroy existing player if any
    if (hlsPlayer) {
        hlsPlayer.destroy();
        hlsPlayer = null;
    }
    
    // Create new HLS instance with robust configuration for live streaming
    // Key settings to prevent bufferStalledError:
    // - Larger buffers to absorb encoding delays
    // - Live stream specific settings
    // - Better stall handling
    hlsPlayer = new Hls({
        enableWorker: true,
        lowLatencyMode: false,  // Disable low latency mode for more stable playback
        liveDurationInfinity: true,  // Treat live stream as infinite duration
        liveBackBufferLength: 0,  // Don't keep back buffer for live streams
        
        // Buffer settings - larger to absorb encoding delays
        backBufferLength: 60,  // Keep 60 seconds of back buffer
        maxBufferLength: 60,  // Target 60 seconds of forward buffer
        maxMaxBufferLength: 300,  // Allow up to 300 seconds max (5 minutes)
        maxBufferSize: 500 * 1000 * 1000,  // 500MB buffer for high bitrate
        maxBufferHole: 1.0,  // Allow larger gaps in buffer
        
        // High buffer size triggers more aggressive parallel loading
        highBufferWatchdogPeriod: 2,  // Check buffer every 2 seconds
        
        // Parallel fragment loading - request multiple fragments ahead
        // HLS.js uses the browser's HTTP connection pool for parallel requests
        // With HTTP/2, multiple fragments can be downloaded in parallel over one connection
        // With HTTP/1.1, browsers allow ~6 concurrent connections per domain
        maxFragBuffered: 6,  // Buffer up to 6 fragments ahead for smoother playback
        
        // Parallel fragment loading - be more aggressive
        // HLS.js uses browser's HTTP connection pool (6 connections for HTTP/1.1, unlimited for HTTP/2)
        startFragPrefetch: true,  // Start prefetching fragments early
        
        // Stall recovery settings
        stallAttempts: 5,  // More stall recovery attempts
        stallTimeLimit: 5,  // Wait 5 seconds before declaring stall
        
        // Quality settings - Adaptive Bitrate Streaming
        startLevel: -1,  // Auto quality selection
        autoStartLoad: true,
        capLevelToPlayerSize: false,  // Don't limit quality based on player size
        restrictPlayerSizeToQuality: false,  // Don't resize player
        
        // ABR (Adaptive Bitrate) settings - tuned for higher quality preference
        abrEwmaFastLive: 5.0,  // Faster adaptation for live
        abrEwmaSlowLive: 15.0,  // Slower decay for sustained high quality
        abrEwmaFastVoD: 5.0,
        abrEwmaSlowVoD: 15.0,
        abrMaxWithRealBitrate: true,  // Use real bitrate for ABR decisions
        maxStarvationDelay: 8,  // Allow more delay before switching down
        maxLoadingDelay: 8,  // Allow more loading delay before switching
        
        // Initial bandwidth estimate - start high to prefer higher quality
        // This helps HLS.js choose higher quality from the start
        testBandwidth: true,  // Test bandwidth on start
        
        // Retry settings for network issues
        manifestLoadingTimeOut: 10000,
        manifestLoadingMaxRetry: 10,
        manifestLoadingRetryDelay: 1000,
        levelLoadingTimeOut: 10000,
        levelLoadingMaxRetry: 10,
        levelLoadingRetryDelay: 1000,
        fragLoadingTimeOut: 30000,
        fragLoadingMaxRetry: 10,
        fragLoadingRetryDelay: 1000,
        
        // Start from live edge with some buffer
        startPosition: -1,  // Start from live edge
    });
    
    hlsPlayer.attachMedia(video);
    
    // Handle video ended - reload manifest to get new content
    video.addEventListener('ended', function() {
        console.log('HLS.js: video ended, reloading manifest for new content');
        updateStreamStatus('buffering');
        
        // Reload the stream after a short delay
        setTimeout(() => {
            if (hlsPlayer) {
                console.log('Reloading HLS stream after video ended');
                hlsPlayer.loadSource(HLS_STREAM_URL + '?t=' + Date.now()); // Cache bust
            }
        }, 1000);
    });
    
    // Set up event handlers
    hlsPlayer.on(Hls.Events.MANIFEST_PARSED, function(event, data) {
        console.log('HLS manifest parsed, starting playback');
        debugLog('HLS', 'Manifest parsed, levels: ' + (data.levels ? data.levels.length : 0));
        reconnectAttempts = 0;  // Reset reconnect attempts on success
        isStreamActive = true;
        updateStreamStatus('live');
        setDebugError('none');
        
        // Log available quality levels
        if (hlsPlayer.levels && hlsPlayer.levels.length > 0) {
            console.log('HLS: Available quality levels:');
            hlsPlayer.levels.forEach((level, index) => {
                console.log(`  [${index}] ${level.width}x${level.height} @ ${Math.round(level.bitrate/1000)}kbps (${level.name || 'unnamed'})`);
            });
        }
        
        // Notify overlay controller that stream is live
        if (overlayController) {
            overlayController.onStreamStart();
        }
        
        video.play().catch(e => {
            console.warn('Autoplay blocked, user interaction required:', e);
            debugLog('HLS', 'Autoplay blocked: ' + e.message);
            showNotification('Click the video to start playback', 'info');
        });
    });
    
    // Monitor quality level changes
    hlsPlayer.on(Hls.Events.LEVEL_SWITCHED, function(event, data) {
        const level = data.level;
        const levelInfo = hlsPlayer.levels[level];
        if (levelInfo) {
            console.log(`HLS: Switched to quality level ${level}: ${levelInfo.width}x${levelInfo.height} @ ${Math.round(levelInfo.bitrate/1000)}kbps`);
            debugLog('HLS', `Quality: ${levelInfo.width}x${levelInfo.height} @ ${Math.round(levelInfo.bitrate/1000)}kbps`);
        }
    });
    
    // Monitor bandwidth estimates
    hlsPlayer.on(Hls.Events.FRAG_LOADED, function(event, data) {
        // Log bandwidth estimate periodically
        if (hlsPlayer.bandwidthEstimate) {
            const bwMbps = Math.round(hlsPlayer.bandwidthEstimate / 1000000);
            // Only log every 50 fragments to avoid spam
            if (data.frag && data.frag.sn % 50 === 0) {
                console.log(`HLS: Bandwidth estimate: ${bwMbps} Mbps`);
            }
        }
    });
    
    hlsPlayer.on(Hls.Events.FRAG_LOADED, function(event, data) {
        // Reset reconnect attempts on successful fragment load
        if (reconnectAttempts > 0) {
            reconnectAttempts = 0;
            updateStreamStatus('live');
        }
        
        // Debug log fragment info
        if (debugMode && data && data.frag) {
            debugLog('FRAG', `Loaded fragment ${data.frag.sn} duration: ${data.frag.duration?.toFixed(2)}s`);
        }
    });
    
    // Handle errors with automatic recovery
    hlsPlayer.on(Hls.Events.ERROR, function(event, data) {
        console.error('HLS error:', data.type, data.details, data);
        debugLog('ERROR', `${data.type}: ${data.details}`, data);
        setDebugError(`${data.type}: ${data.details}`);
        
        if (data.fatal) {
            handleFatalHlsError(video, data);
        } else {
            // Handle non-fatal errors
            handleNonFatalHlsError(video, data);
        }
    });
    
    // Handle buffer stall events specifically
    hlsPlayer.on(Hls.Events.FRAG_LOAD_EMERGENCY_ABORTED, function(event, data) {
        console.warn('Fragment load emergency aborted - buffer issue');
        debugLog('BUFFER', 'Fragment load emergency aborted');
    });
    
    // Handle buffering events
    video.addEventListener('waiting', function() {
        console.log('Video waiting for buffer...');
        debugLog('BUFFER', 'Video waiting for buffer');
        updateStreamStatus('buffering');
    });
    
    video.addEventListener('canplay', function() {
        console.log('Video can play - buffer ready');
        debugLog('BUFFER', 'Video can play - buffer ready');
        if (isStreamActive) {
            updateStreamStatus('live');
        }
    });
    
    video.addEventListener('playing', function() {
        console.log('Video playing');
        debugLog('PLAYBACK', 'Video playing');
        updateStreamStatus('live');
    });
    
    // Debug: Log buffer state periodically
    if (debugMode) {
        setInterval(() => {
            if (video.buffered && video.buffered.length > 0) {
                const ranges = [];
                for (let i = 0; i < video.buffered.length; i++) {
                    ranges.push(`[${video.buffered.start(i).toFixed(1)}-${video.buffered.end(i).toFixed(1)}]`);
                }
                debugLog('BUFFER', `Buffer ranges: ${ranges.join(', ')} | currentTime: ${video.currentTime.toFixed(1)}`);
            }
        }, 5000);
    }
    
    // Load the stream
    loadHlsStream();
}

// Handle fatal HLS errors with recovery attempts
function handleFatalHlsError(video, errorData) {
    updateStreamStatus('error');
    
    switch (errorData.type) {
        case Hls.ErrorTypes.NETWORK_ERROR:
            console.error('Fatal network error:', errorData.details);
            // Try to recover from network errors
            if (reconnectAttempts < HLS_MAX_RECONNECT_ATTEMPTS) {
                scheduleReconnect('Network error - reconnecting...');
            } else {
                showNotification('Stream unavailable. Click refresh to try again.', 'error');
            }
            break;
            
        case Hls.ErrorTypes.MEDIA_ERROR:
            console.error('Fatal media error:', errorData.details);
            // Try to recover from media errors
            if (hlsPlayer && hlsPlayer.recoverMediaError) {
                console.log('Attempting media error recovery...');
                hlsPlayer.recoverMediaError();
            } else {
                scheduleReconnect('Media error - reconnecting...');
            }
            break;
            
        default:
            console.error('Fatal error:', errorData.type, errorData.details);
            scheduleReconnect('Stream error - reconnecting...');
            break;
    }
}

// Handle non-fatal HLS errors (like bufferStalledError)
function handleNonFatalHlsError(video, errorData) {
    switch (errorData.details) {
        case 'bufferStalledError':
            // Buffer stall - this is common in live streams
            // HLS.js will auto-recover, just log it
            console.warn('Buffer stall detected - HLS.js will auto-recover');
            updateStreamStatus('buffering');
            break;
            
        case 'bufferNudgeOnStall':
            // HLS.js nudged playback to recover from stall
            console.log('Buffer nudge applied to recover from stall');
            break;
            
        case 'fragLoadTimeOut':
            // Fragment load timeout - might recover
            console.warn('Fragment load timeout - may need to reconnect');
            break;
            
        default:
            console.warn('Non-fatal HLS error:', errorData.details);
    }
}

// Schedule a reconnection attempt with exponential backoff
function scheduleReconnect(message) {
    if (reconnectTimeout) {
        clearTimeout(reconnectTimeout);
    }
    
    reconnectAttempts++;
    totalReconnectAttempts++;  // Track total for debug display
    const delay = Math.min(HLS_RECONNECT_DELAY * Math.pow(2, reconnectAttempts - 1), HLS_MAX_RECONNECT_DELAY);
    
    console.log(`${message} Attempt ${reconnectAttempts}/${HLS_MAX_RECONNECT_ATTEMPTS} in ${delay}ms`);
    updateStreamStatus('reconnecting');
    showNotification(`${message} (${reconnectAttempts}/${HLS_MAX_RECONNECT_ATTEMPTS})`, 'warning');
    
    reconnectTimeout = setTimeout(() => {
        if (reconnectAttempts <= HLS_MAX_RECONNECT_ATTEMPTS) {
            loadHlsStream();
        }
    }, delay);
}

// Load the HLS stream
function loadHlsStream() {
    if (hlsPlayer) {
        console.log('Loading HLS stream:', HLS_STREAM_URL);
        hlsPlayer.loadSource(HLS_STREAM_URL);
    }
}

// Initialize native HLS (Safari, iOS)
function initializeNativeHls(video) {
    video.src = HLS_STREAM_URL;
    
    // Track if we're waiting for new content
    let waitingForNewContent = false;
    let checkNewContentInterval = null;
    
    video.addEventListener('loadedmetadata', function() {
        console.log('Native HLS: metadata loaded, starting playback');
        reconnectAttempts = 0;
        isStreamActive = true;
        waitingForNewContent = false;
        updateStreamStatus('live');
        video.play().catch(e => console.warn('Autoplay blocked:', e));
    });
    
    video.addEventListener('error', function(e) {
        console.error('Native HLS error:', e);
        updateStreamStatus('error');
        
        if (reconnectAttempts < HLS_MAX_RECONNECT_ATTEMPTS) {
            reconnectAttempts++;
            totalReconnectAttempts++;  // Track total for debug display
            setTimeout(() => {
                video.src = HLS_STREAM_URL + '?t=' + Date.now(); // Cache bust
                video.load();
            }, HLS_RECONNECT_DELAY * reconnectAttempts);
        } else {
            showNotification('Stream unavailable. Click refresh to try again.', 'error');
        }
    });
    
    video.addEventListener('stalled', function() {
        console.warn('Video playback stalled');
        updateStreamStatus('buffering');
    });
    
    video.addEventListener('waiting', function() {
        updateStreamStatus('buffering');
    });
    
    video.addEventListener('playing', function() {
        updateStreamStatus('live');
        waitingForNewContent = false;
        if (checkNewContentInterval) {
            clearInterval(checkNewContentInterval);
            checkNewContentInterval = null;
        }
    });
    
    // Handle video ended - reload manifest to get new content
    video.addEventListener('ended', function() {
        console.log('Native HLS: video ended, reloading manifest for new content');
        updateStreamStatus('buffering');
        waitingForNewContent = true;
        
        // Reload the stream after a short delay
        setTimeout(() => {
            if (waitingForNewContent) {
                video.src = HLS_STREAM_URL + '?t=' + Date.now(); // Cache bust
                video.load();
                video.play().catch(e => console.warn('Autoplay blocked on reload:', e));
            }
        }, 1000);
        
        // Set up interval to keep checking for new content
        checkNewContentInterval = setInterval(() => {
            if (!waitingForNewContent) {
                clearInterval(checkNewContentInterval);
                checkNewContentInterval = null;
                return;
            }
            console.log('Checking for new stream content...');
            video.src = HLS_STREAM_URL + '?t=' + Date.now();
            video.load();
            video.play().catch(e => console.warn('Autoplay blocked:', e));
        }, 5000);
    });
    
    video.load();
}

// Update stream status indicator
function updateStreamStatus(status) {
    const statusElement = document.getElementById('stream-status');
    if (statusElement) {
        const statusConfig = {
            'live': { text: '● LIVE', class: 'status-live' },
            'buffering': { text: '⟳ Buffering...', class: 'status-buffering' },
            'reconnecting': { text: '⟳ Reconnecting...', class: 'status-reconnecting' },
            'error': { text: '✕ Error', class: 'status-error' },
            'offline': { text: '○ Offline', class: 'status-offline' }
        };
        
        const config = statusConfig[status] || statusConfig['offline'];
        statusElement.textContent = config.text;
        statusElement.className = 'stream-status ' + config.class;
    }
    
    // Notify overlay controller of status change
    if (overlayController) {
        if (status === 'live') {
            overlayController.onStreamStart();
        } else if (status === 'error' || status === 'offline') {
            overlayController.onStreamStop();
        }
    }
}

// Load live stream (for API compatibility - now just ensures stream is playing)
async function loadLiveStream(matchId) {
    // The stream is always at /hls/stream.m3u8
    // Just ensure the player is initialized and playing
    if (!hlsPlayer && !document.getElementById('hls-player').src) {
        initializeAndStartStream();
    }
    
    // Update match info display
    try {
        const streamData = await apiRequest('/player/video-stream');
        const matchInfo = streamData.video_stream?.match_info || streamData.match_info || 'Live Stream';
        document.getElementById('match-info').textContent = matchInfo;
    } catch (error) {
        console.warn('Could not fetch stream info:', error);
        document.getElementById('match-info').textContent = 'Live Stream';
    }
}

// Refresh stream - force reload
function refreshStream() {
    console.log('Manual stream refresh requested');
    reconnectAttempts = 0;  // Reset attempts on manual refresh
    streamInitialized = false;  // Reset initialization flag to allow re-initialization
    
    if (reconnectTimeout) {
        clearTimeout(reconnectTimeout);
        reconnectTimeout = null;
    }
    
    const video = document.getElementById('hls-player');
    
    if (hlsPlayer) {
        hlsPlayer.destroy();
        hlsPlayer = null;
    }
    
    video.src = '';
    video.load();
    
    showNotification('Refreshing stream...', 'info');
    initializeAndStartStream();
}

// Display recent bets
function displayRecentBets(bets) {
    const container = document.getElementById('recent-bets');
    
    if (bets.length === 0) {
        container.innerHTML = '<p>No recent bets.</p>';
        return;
    }
    
    container.innerHTML = bets.map(bet => `
        <div style="padding: 10px; border-bottom: 1px solid var(--border-color);">
            <p><strong>${bet.match}</strong></p>
            <p>Outcome: ${bet.outcome}</p>
            <p>Amount: $${bet.amount.toFixed(2)}</p>
            <p>Status: <span style="color: ${getStatusColor(bet.status)}">${bet.status}</span></p>
        </div>
    `).join('');
}

// Get status color
function getStatusColor(status) {
    switch (status.toLowerCase()) {
        case 'won':
            return 'var(--success-color)';
        case 'lost':
            return 'var(--error-color)';
        case 'pending':
            return 'var(--accent-color)';
        default:
            return 'var(--text-muted)';
    }
}

// Display upcoming matches
function displayUpcomingMatches(matches) {
    const container = document.getElementById('upcoming-matches');
    
    if (matches.length === 0) {
        container.innerHTML = '<p>No upcoming matches scheduled.</p>';
        return;
    }
    
    container.innerHTML = matches.map(match => `
        <div style="padding: 15px; border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; align-items: center;">
            <div>
                <p><strong>${match.fighter1 || match.home_team} vs ${match.fighter2 || match.away_team}</strong></p>
                <p style="color: var(--text-muted);">${match.start_time || match.date || 'TBD'}</p>
            </div>
            <button class="btn btn-primary" style="padding: 8px 16px; font-size: 0.8rem;" onclick="selectMatch('${match.id}')">View Odds</button>
        </div>
    `).join('');
}

// Select match from upcoming list
function selectMatch(matchId) {
    document.getElementById('match-select').value = matchId;
    loadMatchOdds();
    window.scrollTo({ top: 0, behavior: 'smooth' });
}

// View all bets
function viewAllBets() {
    // This would navigate to a full bets history page
    showNotification('Full bet history coming soon!', 'success');
}

// Show deposit modal
function showDepositModal() {
    document.getElementById('deposit-modal').style.display = 'block';
}

// Show withdraw modal
function showWithdrawModal() {
    document.getElementById('withdraw-modal').style.display = 'block';
}

// Close modal
function closeModal(modalId) {
    document.getElementById(modalId).style.display = 'none';
}

// Process deposit
async function processDeposit() {
    const amount = parseFloat(document.getElementById('deposit-amount').value);
    const method = document.getElementById('payment-method').value;
    
    if (!amount || amount < 10) {
        showNotification('Minimum deposit amount is $10.', 'error');
        return;
    }
    
    try {
        await apiRequest('/player/deposit', {
            method: 'POST',
            body: JSON.stringify({
                amount: amount,
                method: method
            })
        });
        
        showNotification('Deposit processed successfully!', 'success');
        closeModal('deposit-modal');
        document.getElementById('deposit-amount').value = '';
        
        // Reload player data
        loadPlayerData();
    } catch (error) {
        console.error('Error processing deposit:', error);
        showNotification('Failed to process deposit. Please try again.', 'error');
    }
}

// Process withdrawal
async function processWithdrawal() {
    const amount = parseFloat(document.getElementById('withdraw-amount').value);
    const method = document.getElementById('withdraw-method').value;
    
    if (!amount || amount < 10) {
        showNotification('Minimum withdrawal amount is $10.', 'error');
        return;
    }
    
    try {
        await apiRequest('/player/withdraw', {
            method: 'POST',
            body: JSON.stringify({
                amount: amount,
                method: method
            })
        });
        
        showNotification('Withdrawal request submitted successfully!', 'success');
        closeModal('withdraw-modal');
        document.getElementById('withdraw-amount').value = '';
        
        // Reload player data
        loadPlayerData();
    } catch (error) {
        console.error('Error processing withdrawal:', error);
        showNotification('Failed to process withdrawal. Please try again.', 'error');
    }
}

// Listen for bet amount changes (only if element exists)
const betAmountInput = document.getElementById('bet-amount');
if (betAmountInput) {
    betAmountInput.addEventListener('input', updateBetSummary);
}

// Close modals when clicking outside
window.addEventListener('click', (e) => {
    if (e.target.classList.contains('modal')) {
        e.target.style.display = 'none';
    }
});

// Video time update handler for overlay synchronization
function setupVideoTimeSync() {
    const video = document.getElementById('hls-player');
    if (!video) return;
    
    video.addEventListener('timeupdate', function() {
        if (overlayController && isStreamActive) {
            overlayController.onVideoTimeUpdate(video.currentTime, video.duration || 0);
        }
    });
    
    video.addEventListener('seeked', function() {
        if (overlayController) {
            overlayController.onVideoSeek(video.currentTime);
        }
    });
    
    video.addEventListener('play', function() {
        if (overlayController) {
            overlayController.onStreamStart();
        }
    });
    
    video.addEventListener('pause', function() {
        if (overlayController) {
            overlayController.onStreamPause();
        }
    });
    
    video.addEventListener('ended', function() {
        if (overlayController) {
            overlayController.onStreamStop();
        }
    });
    
    // Handle fullscreen changes - move overlay to fullscreen element
    setupFullscreenHandler(video);
}

// Handle fullscreen changes to keep overlay visible
function setupFullscreenHandler(video) {
    const overlayContainer = document.getElementById('overlay-container');
    const videoWrapper = document.querySelector('.video-wrapper');
    
    if (!overlayContainer || !videoWrapper) return;
    
    // Intercept fullscreen requests on video element to use wrapper instead
    video.addEventListener('fullscreenchange', function(e) {
        // If video went fullscreen, exit and make wrapper fullscreen instead
        if (document.fullscreenElement === video) {
            document.exitFullscreen().then(() => {
                videoWrapper.requestFullscreen().catch(err => {
                    console.log('Could not make wrapper fullscreen:', err);
                });
            }).catch(err => {
                console.log('Could not exit video fullscreen:', err);
            });
        }
    });
    
    video.addEventListener('webkitfullscreenchange', function(e) {
        if (document.webkitFullscreenElement === video) {
            document.webkitExitFullscreen();
            setTimeout(() => {
                videoWrapper.webkitRequestFullscreen();
            }, 100);
        }
    });
    
    function handleFullscreenChange() {
        const isFullscreen = !!(document.fullscreenElement || document.webkitFullscreenElement ||
                               document.mozFullScreenElement || document.msFullscreenElement);
        
        console.log('Fullscreen change:', isFullscreen ? 'entered' : 'exited');
        
        const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement ||
                                  document.mozFullScreenElement || document.msFullscreenElement;
        
        if (isFullscreen && fullscreenElement) {
            // Ensure overlay is visible in fullscreen
            overlayContainer.style.display = 'block';
            overlayContainer.classList.add('fullscreen');
            
            // If fullscreen element is not the wrapper, try to move overlay
            if (fullscreenElement !== videoWrapper && fullscreenElement.tagName !== 'VIDEO') {
                fullscreenElement.appendChild(overlayContainer);
            }
        } else {
            // Exiting fullscreen - restore overlay to wrapper
            overlayContainer.classList.remove('fullscreen');
            if (overlayContainer.parentElement !== videoWrapper) {
                videoWrapper.appendChild(overlayContainer);
            }
        }
    }
    
    // Listen for fullscreen changes on all vendors
    document.addEventListener('fullscreenchange', handleFullscreenChange);
    document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
    document.addEventListener('mozfullscreenchange', handleFullscreenChange);
    document.addEventListener('MSFullscreenChange', handleFullscreenChange);
}

// Initialize video time sync after DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
    // Small delay to ensure video element exists
    setTimeout(setupVideoTimeSync, 100);
});

// Toggle overlay visibility
function toggleOverlay() {
    const overlayContainer = document.getElementById('overlay-container');
    const toggleBtn = document.getElementById('overlay-toggle-btn');
    
    if (overlayContainer) {
        if (overlayContainer.style.display === 'none') {
            overlayContainer.style.display = 'block';
            if (toggleBtn) toggleBtn.textContent = 'Hide Overlay';
            if (overlayController) overlayController.resume();
        } else {
            overlayContainer.style.display = 'none';
            if (toggleBtn) toggleBtn.textContent = 'Show Overlay';
            if (overlayController) overlayController.pause();
        }
    }
}

// Toggle user dropdown menu
function toggleUserDropdown() {
    const dropdown = document.getElementById('user-dropdown');
    if (dropdown) {
        dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';
    }
}

// Close dropdown when clicking outside
document.addEventListener('click', function(e) {
    const dropdown = document.getElementById('user-dropdown');
    const userProfile = document.querySelector('.user-profile');
    if (dropdown && userProfile && !userProfile.contains(e.target)) {
        dropdown.style.display = 'none';
    }
});

// Simple MD5 hash function for Gravatar
function md5Hash(string) {
    function md5cycle(x, k) {
        var a = x[0], b = x[1], c = x[2], d = x[3];
        a = ff(a, b, c, d, k[0], 7, -680876936);
        d = ff(d, a, b, c, k[1], 12, -389564586);
        c = ff(c, d, a, b, k[2], 17, 606105819);
        b = ff(b, c, d, a, k[3], 22, -1044525330);
        a = ff(a, b, c, d, k[4], 7, -176418897);
        d = ff(d, a, b, c, k[5], 12, 1200080426);
        c = ff(c, d, a, b, k[6], 17, -1473231341);
        b = ff(b, c, d, a, k[7], 22, -45705983);
        a = ff(a, b, c, d, k[8], 7, 1770035416);
        d = ff(d, a, b, c, k[9], 12, -1958414417);
        c = ff(c, d, a, b, k[10], 17, -42063);
        b = ff(b, c, d, a, k[11], 22, -1990404162);
        a = ff(a, b, c, d, k[12], 7, 1804603682);
        d = ff(d, a, b, c, k[13], 12, -40341101);
        c = ff(c, d, a, b, k[14], 17, -1502002290);
        b = ff(b, c, d, a, k[15], 22, 1236535329);
        a = gg(a, b, c, d, k[1], 5, -165796510);
        d = gg(d, a, b, c, k[6], 9, -1069501632);
        c = gg(c, d, a, b, k[11], 14, 643717713);
        b = gg(b, c, d, a, k[0], 20, -373897302);
        a = gg(a, b, c, d, k[5], 5, -701558691);
        d = gg(d, a, b, c, k[10], 9, 38016083);
        c = gg(c, d, a, b, k[15], 14, -660478335);
        b = gg(b, c, d, a, k[4], 20, -405537848);
        a = gg(a, b, c, d, k[9], 5, 568446438);
        d = gg(d, a, b, c, k[14], 9, -1019803690);
        c = gg(c, d, a, b, k[3], 14, -187363961);
        b = gg(b, c, d, a, k[8], 20, 1163531501);
        a = gg(a, b, c, d, k[13], 5, -1444681467);
        d = gg(d, a, b, c, k[2], 9, -51403784);
        c = gg(c, d, a, b, k[7], 14, 1735328473);
        b = gg(b, c, d, a, k[12], 20, -1926607734);
        a = hh(a, b, c, d, k[5], 4, -378558);
        d = hh(d, a, b, c, k[8], 11, -2022574463);
        c = hh(c, d, a, b, k[11], 16, 1839030562);
        b = hh(b, c, d, a, k[14], 23, -35309556);
        a = hh(a, b, c, d, k[1], 4, -1530992060);
        d = hh(d, a, b, c, k[4], 11, 1272893353);
        c = hh(c, d, a, b, k[7], 16, -155497632);
        b = hh(b, c, d, a, k[10], 23, -1094730640);
        a = hh(a, b, c, d, k[13], 4, 681279174);
        d = hh(d, a, b, c, k[0], 11, -358537222);
        c = hh(c, d, a, b, k[3], 16, -722521979);
        b = hh(b, c, d, a, k[6], 23, 76029189);
        a = hh(a, b, c, d, k[9], 4, -640364487);
        d = hh(d, a, b, c, k[12], 11, -421815835);
        c = hh(c, d, a, b, k[15], 16, 530742520);
        b = hh(b, c, d, a, k[2], 23, -995338651);
        a = ii(a, b, c, d, k[0], 6, -198630844);
        d = ii(d, a, b, c, k[7], 10, 1126891415);
        c = ii(c, d, a, b, k[14], 15, -1416354905);
        b = ii(b, c, d, a, k[5], 21, -57434055);
        a = ii(a, b, c, d, k[12], 6, 1700485571);
        d = ii(d, a, b, c, k[3], 10, -1894986606);
        c = ii(c, d, a, b, k[10], 15, -1051523);
        b = ii(b, c, d, a, k[1], 21, -2054922799);
        a = ii(a, b, c, d, k[8], 6, 1873313359);
        d = ii(d, a, b, c, k[15], 10, -30611744);
        c = ii(c, d, a, b, k[6], 15, -1560198380);
        b = ii(b, c, d, a, k[13], 21, 1309151649);
        a = ii(a, b, c, d, k[4], 6, -145523070);
        d = ii(d, a, b, c, k[11], 10, -1120210379);
        c = ii(c, d, a, b, k[2], 15, 718787259);
        b = ii(b, c, d, a, k[9], 21, -343485551);
        x[0] = add32(a, x[0]);
        x[1] = add32(b, x[1]);
        x[2] = add32(c, x[2]);
        x[3] = add32(d, x[3]);
    }
    function cmn(q, a, b, x, s, t) { a = add32(add32(a, q), add32(x, t)); return add32((a << s) | (a >>> (32 - s)), b); }
    function ff(a, b, c, d, x, s, t) { return cmn((b & c) | ((~b) & d), a, b, x, s, t); }
    function gg(a, b, c, d, x, s, t) { return cmn((b & d) | (c & (~d)), a, b, x, s, t); }
    function hh(a, b, c, d, x, s, t) { return cmn(b ^ c ^ d, a, b, x, s, t); }
    function ii(a, b, c, d, x, s, t) { return cmn(c ^ (b | (~d)), a, b, x, s, t); }
    function md51(s) {
        var n = s.length, state = [1732584193, -271733879, -1732584194, 271733878], i;
        for (i = 64; i <= s.length; i += 64) { md5cycle(state, md5blk(s.substring(i - 64, i))); }
        s = s.substring(i - 64);
        var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        for (i = 0; i < s.length; i++) tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
        tail[i >> 2] |= 0x80 << ((i % 4) << 3);
        if (i > 55) { md5cycle(state, tail); for (i = 0; i < 16; i++) tail[i] = 0; }
        tail[14] = n * 8;
        md5cycle(state, tail);
        return state;
    }
    function md5blk(s) {
        var md5blks = [], i;
        for (i = 0; i < 64; i += 4) { md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24); }
        return md5blks;
    }
    var hex_chr = '0123456789abcdef'.split('');
    function rhex(n) { var s = '', j = 0; for (; j < 4; j++) s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; return s; }
    function hex(x) { for (var i = 0; i < x.length; i++) x[i] = rhex(x[i]); return x.join(''); }
    function add32(a, b) { return (a + b) & 0xFFFFFFFF; }
    return hex(md51(string));
}