<script>
    import { onMount, onDestroy } from 'svelte';
    import { page } from '$app/stores';
    import { browser } from '$app/environment';
    import { auth, userColor } from '$lib/stores/auth';
    import { siteSettings } from '$lib/stores/siteSettings';
    import { connectWebSocket, disconnectWebSocket } from '$lib/websocket';
    import { goto } from '$app/navigation';
    import ChatPanel from '$lib/components/chat/ChatPanel.svelte';
    import { chatLayout } from '$lib/stores/chatLayout';
    import { streamTiles } from '$lib/stores/streamTiles';
    import StreamPlayer from '$lib/components/StreamPlayer.svelte';

    // Browser-only imports
    let Hls;
    let OvenPlayer;
    
    // Only import on client side
    if (typeof window !== 'undefined') {
        import('hls.js').then(module => {
            Hls = module.default;
            window.Hls = Hls;
        });
        
        import('ovenplayer').then(module => {
            OvenPlayer = module.default;
            window.OvenPlayer = OvenPlayer;
        });
    }
    
    const STREAM_PORT = import.meta.env.VITE_STREAM_PORT || '8088';

    // Helper functions for dynamic host/protocol detection
    function getStreamHost() {
        if (!browser) return 'localhost';
        return window.location.hostname;
    }

    function getStreamProtocol(secure = false) {
        if (!browser) return secure ? 'https' : 'http';
        return window.location.protocol === 'https:' ? 'https' : 'http';
    }

    function getWsProtocol() {
        if (!browser) return 'ws';
        return window.location.protocol === 'https:' ? 'wss' : 'ws';
    }

    let player;
    let realm = null;
    let streamKey = '';
    let loading = true;
    let error = '';
    let message = '';
    let isStreaming = false;
    let playerPlaying = false;  // Most reliable indicator: true only when player.state === 'playing'
    let playerInitializing = true;  // Grace period to prevent offline flash during player init
    let playerBuffering = false;  // True when player is buffering/loading (intermediate state)
    let heartbeatInterval;
    let viewerToken = null;
    let statsInterval;
    let playerReconnectAttempts = 0;
    const maxPlayerReconnects = 5;
    let llhlsRetryAttempts = 0;
    const maxLlhlsRetries = 3;  // Retry LLHLS 3 times before falling back to WebRTC
    let llhlsRetryTimeout = null;

    // Stats
    let stats = {
        connections: 0,
        bitrate: 0,
        resolution: 'N/A',
        codec: 'N/A',
        fps: 0,
        isLive: false,
        liveStartedAt: null
    };

    // Duration display for live stream
    let durationDisplay = '';
    let durationInterval;
    
    onMount(async () => {
        const realmName = $page.params.realm;
        
        // Load realm info
        await loadRealm(realmName);
        
        if (!realm) {
            error = 'Realm not found';
            loading = false;
            return;
        }
        
        // Get viewer token
        const tokenObtained = await getViewerToken();
        
        if (!tokenObtained) {
            loading = false;
            return;
        }
        
        // Get the actual stream key using the token
        const keyObtained = await getStreamKey();
        
        if (!keyObtained) {
            loading = false;
            return;
        }
        
        // Wait for dependencies
        const checkDependencies = async () => {
            let attempts = 0;
            while ((!window.Hls || !window.OvenPlayer) && attempts < 20) {
                await new Promise(resolve => setTimeout(resolve, 100));
                attempts++;
            }
            
            if (!window.Hls || !window.OvenPlayer) {
                console.error('Failed to load dependencies');
                error = 'Failed to load player dependencies';
                return false;
            }
            return true;
        };
        
        const depsLoaded = await checkDependencies();
        if (!depsLoaded) {
            loading = false;
            return;
        }
        
        // Initialize player after a short delay
        setTimeout(initializePlayer, 100);
        
        // Start heartbeat
        startHeartbeat();
        
        // Start stats polling
        startStatsPolling();
        
        // Connect WebSocket
        connectWebSocket((data) => {
            if (data.type === 'stats_update' && data.stream_key === streamKey) {
                updateStatsFromData(data.stats);
            }
        });
        
        loading = false;
    });
    
    onDestroy(() => {
        if (player) {
            player.remove();
        }
        if (heartbeatInterval) {
            clearInterval(heartbeatInterval);
        }
        if (statsInterval) {
            clearInterval(statsInterval);
        }
        if (durationInterval) {
            clearInterval(durationInterval);
        }
        if (llhlsRetryTimeout) {
            clearTimeout(llhlsRetryTimeout);
        }
        disconnectWebSocket();
    });
    
    async function loadRealm(realmName) {
        try {
            const response = await fetch(`/api/realms/by-name/${realmName}`);
            if (response.ok) {
                const data = await response.json();
                realm = data.realm;
                // Initialize liveStartedAt from realm data if stream is live
                if (realm.isLive && realm.liveStartedAt) {
                    stats.liveStartedAt = realm.liveStartedAt;
                    stats.isLive = true;
                    startDurationTimer();
                }
                // Get the stream key from the database
                const keyResponse = await fetch(`/api/realms/${realm.id}`);
                if (keyResponse.ok && keyResponse.status !== 404) {
                    const keyData = await keyResponse.json();
                    if (keyData.success && keyData.realm && keyData.realm.streamKey) {
                        streamKey = keyData.realm.streamKey;
                    }
                } else {
                    // If we can't get the key directly, we'll need to rely on the backend
                    // to validate tokens against the realm
                    streamKey = 'realm-' + realm.id;
                }
            } else if (response.status === 404) {
                error = 'Realm not found';
            }
        } catch (e) {
            console.error('Failed to load realm:', e);
            error = 'Failed to load realm';
        }
    }
    
    async function getViewerToken() {
        if (!realm) return;
        
        try {
            const response = await fetch(`/api/realms/${realm.id}/viewer-token`, {
                credentials: 'include'
            });
            
            if (response.ok) {
                const data = await response.json();
                viewerToken = data.viewer_token;
                console.log('Viewer token obtained');
                
                // Now we need to get the actual stream key for the player
                // This will be handled server-side via the token
                return true;
            } else {
                console.error('Failed to get viewer token');
                error = 'Failed to authenticate for stream';
                return false;
            }
        } catch (e) {
            console.error('Error getting viewer token:', e);
            error = 'Failed to authenticate for stream';
            return false;
        }
    }
    
    async function getStreamKey() {
        if (!realm || !viewerToken) return false;
        
        try {
            const response = await fetch(`/api/realms/${realm.id}/stream-key`, {
                credentials: 'include'
            });
            
            if (response.ok) {
                const data = await response.json();
                streamKey = data.streamKey;
                console.log('Stream key obtained');
                return true;
            } else {
                console.error('Failed to get stream key');
                error = 'Failed to get stream key';
                return false;
            }
        } catch (e) {
            console.error('Error getting stream key:', e);
            error = 'Failed to get stream key';
            return false;
        }
    }
    
    function startHeartbeat() {
        heartbeatInterval = setInterval(async () => {
            if (streamKey && viewerToken) {
                try {
                    const response = await fetch(`/api/stream/heartbeat/${streamKey}`, {
                        method: 'POST',
                        credentials: 'include'
                    });
                    
                    if (!response.ok) {
                        console.error('Heartbeat failed, getting new token');
                        await getViewerToken();
                    }
                } catch (error) {
                    console.error('Heartbeat error:', error);
                }
            }
        }, 10000);
    }
    
    function startStatsPolling() {
        statsInterval = setInterval(async () => {
            if (realm) {
                try {
                    const response = await fetch(`/api/realms/${realm.id}/stats`);
                    const data = await response.json();
                    if (data.success && data.stats) {
                        updateStatsFromData(data.stats);
                    }
                } catch (error) {
                    console.error('Failed to fetch stats:', error);
                }
            }
        }, 5000);  // Match backend polling interval (5 seconds)
    }
    
    function updateStatsFromData(data) {
        const wasLive = stats.isLive;
        stats = {
            connections: data.connections || 0,
            bitrate: data.bitrate || 0,
            resolution: data.resolution || 'N/A',
            codec: data.codec || 'N/A',
            fps: data.fps || 0,
            isLive: data.is_live || false,
            liveStartedAt: data.live_started_at || stats.liveStartedAt || null
        };

        // Start/stop duration timer based on live status
        if (stats.isLive && stats.liveStartedAt && !wasLive) {
            startDurationTimer();
        } else if (!stats.isLive && wasLive) {
            stopDurationTimer();
        } else if (stats.isLive && stats.liveStartedAt && !durationInterval) {
            // Ensure timer is running if we're live with a start time
            startDurationTimer();
        }

        // Only update isStreaming from stats if player isn't actively playing
        // This prevents stats from overriding the player's live state during connection
        if (!playerPlaying) {
            isStreaming = stats.isLive;
        }

        // Update viewer count in realm info if different
        if (realm && realm.viewerCount !== stats.connections) {
            realm.viewerCount = stats.connections;
        }
    }
    
    function initializePlayer() {
        const playerElement = document.getElementById('player');
        if (!playerElement) {
            console.error('Player element not found');
            return;
        }
        
        if (!viewerToken || !streamKey) {
            console.error('No viewer token or stream key, cannot initialize player');
            return;
        }
        
        const sources = [];

        if (streamKey) {
            // Dynamic URLs based on current page host/protocol
            const host = getStreamHost();
            const httpProto = getStreamProtocol();
            const wsProto = getWsProtocol();

            // Add all sources - LLHLS first (default), then HLS, then WebRTC as fallback
            sources.push(
                {
                    type: 'hls',
                    file: `${httpProto}://${host}:${STREAM_PORT}/app/${streamKey}/llhls.m3u8?token=${encodeURIComponent(viewerToken)}`,
                    label: 'LLHLS (Low Latency)'
                },
                {
                    type: 'hls',
                    file: `${httpProto}://${host}:${STREAM_PORT}/app/${streamKey}/ts:playlist.m3u8?token=${encodeURIComponent(viewerToken)}`,
                    label: 'HLS (Standard)'
                },
                {
                    type: 'webrtc',
                    file: `${wsProto}://${host}/webrtc/app/${streamKey}`,
                    label: 'WebRTC (Ultra Low Latency)'
                }
            );
        }
        
        const config = {
            autoStart: true,
            autoFallback: false,  // Disable auto-fallback to control source priority manually
            controls: true,
            showBigPlayButton: true,
            watermark: false,
            mute: false,
            aspectRatio: "16:9",
            sources: sources,
            webrtcConfig: {
                timeoutMaxRetry: 4,
                connectionTimeout: 10000
            },
            hlsConfig: {
                debug: false,
                enableWorker: true,
                lowLatencyMode: true,
                backBufferLength: 90,
                // Increased retry settings for LLHLS resilience
                fragLoadingMaxRetry: 6,
                fragLoadingRetryDelay: 1000,
                manifestLoadingMaxRetry: 4,
                levelLoadingMaxRetry: 4,
                maxBufferLength: 30,
                maxBufferHole: 0.5,
                xhrSetup: function(xhr, url) {
                    let finalUrl = url;

                    // Use URL API for proper parameter handling to avoid encoding issues
                    try {
                        const urlObj = new URL(url);
                        if (viewerToken && url.includes('/app/') && !urlObj.searchParams.has('token')) {
                            urlObj.searchParams.set('token', viewerToken);
                            finalUrl = urlObj.toString();
                        }
                    } catch (e) {
                        // Fallback for relative URLs
                        if (viewerToken && url.includes('/app/') && !url.includes('token=')) {
                            const separator = url.includes('?') ? '&' : '?';
                            finalUrl = url + separator + 'token=' + encodeURIComponent(viewerToken);
                        }
                    }

                    xhr.open('GET', finalUrl, true);
                    xhr.withCredentials = true;
                }
            }
        };

        try {
            player = window.OvenPlayer.create('player', config);

            player.on('error', (error) => {
                console.error('Player error:', error);
                playerPlaying = false;

                // Handle auth errors
                if (error.code === 403 || error.code === 401) {
                    playerReconnectAttempts++;
                    console.log(`Player reconnect attempt ${playerReconnectAttempts}/${maxPlayerReconnects}`);

                    if (playerReconnectAttempts >= maxPlayerReconnects) {
                        console.error('Max player reconnect attempts reached');
                        message = 'Unable to connect to stream. Please refresh the page to try again.';
                        return;
                    }

                    getViewerToken().then(() => {
                        if (player) {
                            player.remove();
                            setTimeout(initializePlayer, 500);
                        }
                    });
                    return;
                }

                // Handle source errors - retry LLHLS before falling back to WebRTC
                const currentSource = player.getCurrentSource();
                console.log('Current source index:', currentSource, 'LLHLS retries:', llhlsRetryAttempts);

                if (currentSource === 0) {
                    // Currently on LLHLS (first source)
                    llhlsRetryAttempts++;
                    if (llhlsRetryAttempts <= maxLlhlsRetries) {
                        // Retry LLHLS after a short delay (segments might not be ready yet)
                        console.log(`LLHLS retry ${llhlsRetryAttempts}/${maxLlhlsRetries} in 2 seconds...`);
                        if (llhlsRetryTimeout) clearTimeout(llhlsRetryTimeout);
                        llhlsRetryTimeout = setTimeout(() => {
                            if (player) {
                                console.log('Retrying LLHLS...');
                                player.setCurrentSource(0);  // Re-select LLHLS
                            }
                        }, 2000);
                    } else {
                        // Max LLHLS retries reached, try HLS (source 1)
                        console.log('Max LLHLS retries reached, trying HLS...');
                        player.setCurrentSource(1);
                    }
                } else if (currentSource === 1) {
                    // HLS failed, fall back to WebRTC (source 2)
                    console.log('HLS failed, falling back to WebRTC...');
                    player.setCurrentSource(2);
                } else {
                    // WebRTC also failed - stream might be offline
                    console.log('All sources failed - stream may be offline');
                    isStreaming = false;
                }
            });

            player.on('stateChanged', (data) => {
                console.log('Player state changed:', data.newstate);

                // Track buffering state - player is trying to connect
                if (data.newstate === 'loading' || data.newstate === 'buffering' || data.newstate === 'stalled') {
                    playerBuffering = true;
                } else {
                    playerBuffering = false;
                }

                // End initialization grace period on first meaningful state
                if (data.newstate === 'playing' || data.newstate === 'paused' || data.newstate === 'error') {
                    playerInitializing = false;
                }

                if (data.newstate === 'playing') {
                    playerPlaying = true;
                    isStreaming = true;
                    message = '';
                    playerReconnectAttempts = 0; // Reset on successful playback
                    llhlsRetryAttempts = 0;  // Reset LLHLS retries on success
                    if (llhlsRetryTimeout) {
                        clearTimeout(llhlsRetryTimeout);
                        llhlsRetryTimeout = null;
                    }
                } else if (data.newstate === 'error' || data.newstate === 'idle') {
                    playerPlaying = false;
                    // Don't set isStreaming = false here - let stats decide when stream is truly offline
                    // This prevents flickering when player temporarily enters idle/error states
                }
            });

            player.on('play', () => {
                playerInitializing = false;
                playerPlaying = true;
                isStreaming = true;
                playerReconnectAttempts = 0; // Reset on successful play
                llhlsRetryAttempts = 0;  // Reset LLHLS retries on success
            });

            // Fallback: end initialization grace period after 5 seconds
            // This ensures offline overlay shows if stream truly isn't live
            // 5s gives LLHLS enough time to buffer and start playing
            setTimeout(() => {
                playerInitializing = false;
            }, 5000);
            
        } catch (e) {
            console.error('Failed to create player:', e);
            error = 'Failed to initialize player';
        }
    }
    
    function formatBitrate(bitrate) {
        if (bitrate > 1000000) {
            return (bitrate / 1000000).toFixed(2) + ' Mbps';
        } else if (bitrate > 1000) {
            return (bitrate / 1000).toFixed(0) + ' Kbps';
        } else {
            return bitrate + ' bps';
        }
    }

    function formatDuration(startTime) {
        if (!startTime) return '';
        const elapsed = Math.floor((Date.now() - new Date(startTime).getTime()) / 1000);
        if (elapsed < 0) return '0:00';
        const hours = Math.floor(elapsed / 3600);
        const minutes = Math.floor((elapsed % 3600) / 60);
        const seconds = elapsed % 60;

        if (hours > 0) {
            return `${hours}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
        }
        return `${minutes}:${String(seconds).padStart(2, '0')}`;
    }

    function startDurationTimer() {
        if (durationInterval) return;
        durationDisplay = formatDuration(stats.liveStartedAt);
        durationInterval = setInterval(() => {
            durationDisplay = formatDuration(stats.liveStartedAt);
        }, 1000);
    }

    function stopDurationTimer() {
        if (durationInterval) {
            clearInterval(durationInterval);
            durationInterval = null;
        }
        durationDisplay = '';
    }

    // Tiled streams (exclude current stream)
    $: tiledStreams = $streamTiles.streams.filter(s => s.streamKey !== streamKey);
    $: hasTiledStreams = tiledStreams.length > 0;
    $: totalStreams = hasTiledStreams ? tiledStreams.length + 1 : 1; // +1 for main stream
    $: gridClass = totalStreams === 2 ? 'grid-2' : totalStreams >= 3 ? 'grid-4' : '';

    // Track previous layout to detect changes
    let prevTotalStreams = 1;

    // Reinitialize main player when layout changes (DOM element gets recreated)
    $: if (browser && totalStreams !== prevTotalStreams && viewerToken && streamKey) {
        prevTotalStreams = totalStreams;
        // Wait for DOM to update, then reinitialize player
        setTimeout(() => {
            if (player) {
                try {
                    player.remove();
                } catch (e) {}
                player = null;
            }
            // Reset player states
            llhlsRetryAttempts = 0;
            playerInitializing = true;
            initializePlayer();
        }, 100);
    }

    // Resizable dividers
    let isDraggingH = false;
    let isDraggingV = false;
    let gridContainer;

    function startHorizontalDrag(e) {
        isDraggingH = true;
        e.preventDefault();
        document.addEventListener('mousemove', handleHorizontalDrag);
        document.addEventListener('mouseup', stopDrag);
    }

    function startVerticalDrag(e) {
        isDraggingV = true;
        e.preventDefault();
        document.addEventListener('mousemove', handleVerticalDrag);
        document.addEventListener('mouseup', stopDrag);
    }

    function handleHorizontalDrag(e) {
        if (!isDraggingH || !gridContainer) return;
        const rect = gridContainer.getBoundingClientRect();
        const percent = ((e.clientX - rect.left) / rect.width) * 100;
        streamTiles.setHorizontalSplit(percent);
    }

    function handleVerticalDrag(e) {
        if (!isDraggingV || !gridContainer) return;
        const rect = gridContainer.getBoundingClientRect();
        const percent = ((e.clientY - rect.top) / rect.height) * 100;
        streamTiles.setVerticalSplit(percent);
    }

    function stopDrag() {
        isDraggingH = false;
        isDraggingV = false;
        document.removeEventListener('mousemove', handleHorizontalDrag);
        document.removeEventListener('mousemove', handleVerticalDrag);
        document.removeEventListener('mouseup', stopDrag);
    }
</script>

<svelte:head>
    <title>{realm ? `${$siteSettings.site_title} - ${realm.name}` : $siteSettings.site_title}</title>
</svelte:head>

<style>
    .stream-container {
        max-width: 100%;
        margin: 0 auto;
        display: grid;
        grid-template-columns: 1fr 22.2%;
        gap: 0.33rem;
        background: var(--black);
        color: var(--white);
    }
    
    @media (max-width: 1024px) {
        .stream-container {
            grid-template-columns: 1fr;
        }
    }
    
    .player-section {
        width: 100%;
    }
    
    .player-wrapper {
        background: #000;
        border-radius: 12px;
        overflow: hidden;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
        margin-bottom: 1rem;
        position: relative;
    }
    
    
    .player-area {
        position: relative;
    }
    
    .dummy-player {
        padding-bottom: 56.25%; /* 16:9 aspect ratio */
        background: #000;
    }
    
    .player-container {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        width: 100%;
        height: 100%;
    }
    
    #player {
        width: 100%;
        height: 100%;
    }
    
    .stream-info-section {
        background: #111;
        border: 1px solid var(--border);
        border-radius: 8px;
        padding: 1rem;
        position: relative;
        overflow: hidden;
    }

    .stream-info-section::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 4px;
        height: 100%;
        background: var(--user-color, var(--primary));
        opacity: 0.6;
    }

    .stream-header {
        padding-left: 1rem;
    }

    .header-top {
        display: flex;
        align-items: center;
        gap: 0.75rem;
        margin-bottom: 1rem;
    }

    .live-status-badge {
        display: flex;
        align-items: center;
        margin-left: auto;
        background: rgba(255, 255, 255, 0.05);
        border-radius: 4px;
        overflow: hidden;
    }

    .badge-segment {
        font-size: 0.8rem;
        color: var(--gray);
        padding: 0.3rem 0.6rem;
    }

    .badge-segment.status {
        font-weight: 600;
        text-transform: uppercase;
        font-size: 0.75rem;
        letter-spacing: 0.5px;
    }

    .badge-segment.status.live {
        color: #ff4444;
    }

    .badge-divider {
        width: 1px;
        height: 1rem;
        background: rgba(255, 255, 255, 0.15);
    }

    .stream-header h1 {
        margin: 0;
        font-size: 1.5rem;
        color: var(--white);
    }
    
    .streamer-info {
        display: flex;
        align-items: center;
        gap: 0.75rem;
    }

    .streamer-details {
        flex: 1;
    }
    
    .streamer-avatar {
        width: 48px;
        height: 48px;
        border-radius: 50%;
        background: var(--gray);
        position: relative;
        overflow: hidden;
        border: 2px solid var(--border);
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: 600;
        color: var(--white);
        transition: all 0.3s ease;
    }
    
    .streamer-avatar.has-color {
        background: var(--user-color);
        border-color: var(--user-color);
        border-width: 3px;
        box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
    }
    
    .streamer-avatar.has-color.with-image {
        border-width: 3px;
    }
    
    .streamer-avatar img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
    
    .streamer-name {
        font-weight: 600;
        color: var(--white);
        font-size: 1.1rem;
        text-decoration: none;
        transition: color 0.2s;
    }

    .streamer-name:hover {
        color: var(--primary);
    }
    
    .viewer-count {
        font-size: 0.875rem;
        color: var(--gray);
    }

    .compact-stats {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        font-size: 0.875rem;
        color: var(--gray);
        margin-top: 0.25rem;
    }

    .stat-compact {
        color: var(--gray);
    }

    .stat-separator {
        color: rgba(255, 255, 255, 0.3);
        font-weight: bold;
    }

    .stream-description {
        margin-top: 1rem;
        padding: 0.75rem;
        background: rgba(255, 255, 255, 0.03);
        border-radius: 4px;
        color: var(--gray);
        font-size: 0.9rem;
        line-height: 1.5;
        white-space: pre-wrap;
    }

    .sidebar {
        display: flex;
        flex-direction: column;
        gap: 0;
        overflow: hidden;
    }

    .stats-section {
        background: #111;
        border: 1px solid var(--border);
        border-radius: 8px;
        padding: 1.5rem;
        flex-shrink: 0; /* Don't shrink stats section */
    }

    .chat-section {
        background: #111;
        border: 1px solid var(--border);
        border-radius: 8px;
        overflow: hidden;
        flex: 1 1 0; /* Grow and shrink to fill remaining space */
        min-height: 0; /* Allow shrinking below content size */
        display: flex;
        flex-direction: column;
    }
    
    .stats-section h3 {
        margin: 0 0 1rem 0;
        font-size: 1.1rem;
        color: var(--primary);
    }
    
    .status-indicator {
        display: inline-flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0.35rem 0.75rem;
        background: rgba(255, 255, 255, 0.1);
        border-radius: 20px;
        font-size: 0.75rem;
        font-weight: 600;
        letter-spacing: 0.5px;
        text-transform: uppercase;
    }

    .status-indicator.active {
        background: rgba(255, 0, 0, 0.15);
        color: #ff4444;
    }

    .status-indicator.inactive {
        background: rgba(128, 128, 128, 0.2);
        color: var(--gray);
    }

    .status-indicator.active::before {
        content: '';
        display: inline-block;
        width: 6px;
        height: 6px;
        background: #ff0000;
        border-radius: 50%;
        animation: pulse 2s infinite;
    }


    .offline-message {
        text-align: center;
        padding: 4rem 2rem;
        color: var(--gray);
    }

    .offline-icon {
        font-size: 4rem;
        margin-bottom: 1rem;
        opacity: 0.5;
    }

    .offline-image-overlay {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        width: 100%;
        height: 100%;
        z-index: 10;
        background: #000;
        display: flex;
        align-items: center;
        justify-content: center;
        pointer-events: none; /* Allow clicks to pass through to chat sidebar */
    }

    .offline-image-overlay img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .offline-image-overlay .offline-badge {
        position: absolute;
        top: 1rem;
        left: 1rem;
        padding: 0.5rem 1rem;
        background: rgba(0, 0, 0, 0.7);
        color: var(--gray);
        border-radius: 4px;
        font-size: 0.9rem;
        font-weight: 600;
    }

    .offline-placeholder {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 100%;
        background: linear-gradient(135deg, #1a1a1a, #0d0d0d);
    }

    .offline-icon {
        font-size: 4rem;
        color: #444;
        margin-bottom: 1rem;
    }

    .offline-text {
        font-size: 1.5rem;
        color: #555;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.1em;
    }

    .error-container {
        text-align: center;
        padding: 4rem 2rem;
        color: var(--white);
    }
    
    .loading-container {
        text-align: center;
        padding: 4rem 2rem;
        color: var(--gray);
    }
    
    /* Color accent for chat/info sections */
    .color-accent-bar {
        height: 3px;
        background: var(--user-color, var(--primary));
        margin: 0 0 1rem 0;
        border-radius: 2px;
        opacity: 0.8;
    }
    
    /* Pulse animation for live indicator */
    @keyframes pulse {
        0% {
            opacity: 1;
        }
        50% {
            opacity: 0.6;
        }
        100% {
            opacity: 1;
        }
    }

    /* Chat on left side */
    .stream-container.chat-left {
        grid-template-columns: 22.2% 1fr;
    }

    .stream-container.chat-left .player-section {
        order: 2;
    }

    .stream-container.chat-left .sidebar {
        order: 1;
    }

    .stream-container.chat-left .chat-section {
        border-radius: 8px;
    }

    /* Theater mode - overlay chat on video */
    .stream-container.theater-mode {
        grid-template-columns: 1fr;
        position: relative;
    }

    .stream-container.theater-mode .player-section {
        grid-column: 1;
    }

    .stream-container.theater-mode .player-wrapper {
        /* Use nearly full viewport height since stream info is hidden */
        max-width: min(100%, calc(95vh * 16 / 9));
        max-height: 95vh;
        margin: 0 auto; /* Center the video */
    }

    .stream-container.theater-mode .player-area {
        max-height: 95vh;
    }

    .stream-container.theater-mode .dummy-player {
        max-height: 95vh;
    }

    .stream-container.theater-mode .sidebar {
        position: absolute;
        top: 0;
        width: 350px;
        height: 100%;
        z-index: 20; /* Higher than offline-overlay (z-index: 10) */
    }

    .stream-container.theater-mode .sidebar {
        right: 0;
    }

    .stream-container.theater-mode.chat-left .sidebar {
        right: auto;
        left: 0;
    }

    .stream-container.theater-mode .chat-section {
        background: transparent;
        border: none;
        pointer-events: auto; /* Ensure chat section receives pointer events */
    }

    /* Ensure offline overlay matches player constraints in theater mode */
    .stream-container.theater-mode .offline-image-overlay {
        border-radius: 12px; /* Match player-wrapper border-radius */
        max-height: 95vh;
    }

    /* Hide stream info/description bar in theater mode for more video space */
    .stream-container.theater-mode .stream-info-section {
        display: none;
    }

    @media (max-width: 1024px) {
        .stream-container.chat-left {
            grid-template-columns: 1fr;
        }

        .stream-container.chat-left .player-section,
        .stream-container.chat-left .sidebar {
            order: unset;
        }

        .stream-container.theater-mode .sidebar {
            position: relative;
            width: 100%;
        }

        .sidebar {
            height: auto;
            max-height: none;
        }

        .chat-section {
            min-height: 400px;
        }

        .stream-info-section {
            display: none;
        }
    }

    /* Stream grid layout for multiple streams - Resizable */
    /* Grid fills the player-wrapper using absolute positioning */
    .stream-grid {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
    }

    /* When stream-grid is present, player-wrapper needs the dummy for aspect ratio */
    .player-wrapper:has(.stream-grid) {
        position: relative;
    }

    .player-wrapper:has(.stream-grid)::after {
        content: '';
        display: block;
        padding-bottom: 56.25%; /* 16:9 aspect ratio */
    }

    .stream-grid-row {
        display: flex;
        flex: 1;
        min-height: 0;
    }

    .stream-tile-cell {
        flex: 1;
        min-width: 0;
        display: flex;
    }

    .stream-tile-wrapper {
        position: relative;
        background: #000;
        border-radius: 4px;
        overflow: hidden;
        flex: 1;
        display: flex;
        flex-direction: column;
    }

    .stream-tile-wrapper.main-tile {
        /* Main tile has subtle highlight */
    }

    .tile-player-area {
        position: relative;
        flex: 1;
        min-height: 0;
    }

    /* Nested player-area within tiles */
    .stream-tile-wrapper .player-area {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
    }

    .stream-tile-wrapper .dummy-player {
        display: none; /* Not needed when parent has absolute positioning */
    }

    .stream-tile-wrapper .player-container {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
    }

    /* Resizable dividers */
    .resize-divider-h {
        width: 8px;
        cursor: col-resize;
        background: transparent;
        position: relative;
        flex-shrink: 0;
        z-index: 10;
    }

    .resize-divider-h::before {
        content: '';
        position: absolute;
        left: 3px;
        top: 0;
        bottom: 0;
        width: 2px;
        background: #333;
        transition: background 0.15s;
    }

    .resize-divider-h:hover::before,
    .resize-divider-h.dragging::before {
        background: var(--primary, #8b5cf6);
    }

    .resize-divider-v {
        height: 8px;
        cursor: row-resize;
        background: transparent;
        position: relative;
        flex-shrink: 0;
        z-index: 10;
    }

    .resize-divider-v::before {
        content: '';
        position: absolute;
        top: 3px;
        left: 0;
        right: 0;
        height: 2px;
        background: #333;
        transition: background 0.15s;
    }

    .resize-divider-v:hover::before,
    .resize-divider-v.dragging::before {
        background: var(--primary, #8b5cf6);
    }

    /* Empty tile placeholder */
    .stream-tile-wrapper.empty-tile {
        background: #0a0a0a;
        border: 1px dashed #333;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .empty-tile-content {
        color: #444;
        font-size: 0.85rem;
        text-align: center;
    }

    @media (max-width: 768px) {
        .stream-grid {
            flex-direction: column;
        }
        .stream-grid-row {
            flex-direction: column;
        }
        .resize-divider-h,
        .resize-divider-v {
            display: none;
        }
    }
</style>

{#if loading}
    <div class="loading-container">
        <p>Loading stream...</p>
    </div>
{:else if error && !realm}
    <div class="error-container">
        <h1>Stream Not Found</h1>
        <p style="color: var(--gray); margin-top: 1rem;">{error}</p>
        <a href="/" class="btn" style="margin-top: 2rem;">Back to Home</a>
    </div>
{:else if realm}
    <div
        class="stream-container"
        class:chat-left={$chatLayout.position === 'left'}
        class:theater-mode={$chatLayout.theaterMode}
    >
        <div class="player-section">
            <!-- Player wrapper maintains consistent sizing for both single and multi-stream -->
            <div class="player-wrapper">
                {#if hasTiledStreams}
                    <!-- Multi-stream resizable grid layout inside the wrapper -->
                    <div class="stream-grid" bind:this={gridContainer}>
                        {#if totalStreams === 2}
                            <!-- 2 streams: side by side with horizontal divider -->
                            <div class="stream-grid-row">
                                <div class="stream-tile-cell" style="flex: {$streamTiles.horizontalSplit};">
                                    <div class="stream-tile-wrapper main-tile">
                                        <div class="tile-player-area">
                                            <div class="player-area">
                                                <div class="dummy-player"></div>
                                                <div class="player-container">
                                                    <div id="player"></div>
                                                </div>
                                                {#if !stats.isLive && !isStreaming && !playerPlaying && !playerInitializing && !playerBuffering}
                                                    <div class="offline-image-overlay">
                                                        {#if realm.offlineImageUrl}
                                                            <img src={realm.offlineImageUrl} alt="Stream offline" />
                                                        {:else}
                                                            <div class="offline-placeholder">
                                                                <div class="offline-icon">⏸</div>
                                                                <div class="offline-text">{realm.name}</div>
                                                            </div>
                                                        {/if}
                                                        <div class="offline-badge">OFFLINE</div>
                                                    </div>
                                                {/if}
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="resize-divider-h" class:dragging={isDraggingH} on:mousedown={startHorizontalDrag}></div>
                                <div class="stream-tile-cell" style="flex: {100 - $streamTiles.horizontalSplit};">
                                    <StreamPlayer stream={tiledStreams[0]} showClose={true} />
                                </div>
                            </div>
                        {:else if totalStreams >= 3}
                            <!-- 3-4 streams: 2x2 grid with both dividers -->
                            <div class="stream-grid-row" style="flex: {$streamTiles.verticalSplit};">
                                <div class="stream-tile-cell" style="flex: {$streamTiles.horizontalSplit};">
                                    <div class="stream-tile-wrapper main-tile">
                                        <div class="tile-player-area">
                                            <div class="player-area">
                                                <div class="dummy-player"></div>
                                                <div class="player-container">
                                                    <div id="player"></div>
                                                </div>
                                                {#if !stats.isLive && !isStreaming && !playerPlaying && !playerInitializing && !playerBuffering}
                                                    <div class="offline-image-overlay">
                                                        {#if realm.offlineImageUrl}
                                                            <img src={realm.offlineImageUrl} alt="Stream offline" />
                                                        {:else}
                                                            <div class="offline-placeholder">
                                                                <div class="offline-icon">⏸</div>
                                                                <div class="offline-text">{realm.name}</div>
                                                            </div>
                                                        {/if}
                                                        <div class="offline-badge">OFFLINE</div>
                                                    </div>
                                                {/if}
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="resize-divider-h" class:dragging={isDraggingH} on:mousedown={startHorizontalDrag}></div>
                                <div class="stream-tile-cell" style="flex: {100 - $streamTiles.horizontalSplit};">
                                    {#if tiledStreams[0]}
                                        <StreamPlayer stream={tiledStreams[0]} showClose={true} />
                                    {/if}
                                </div>
                            </div>
                            <div class="resize-divider-v" class:dragging={isDraggingV} on:mousedown={startVerticalDrag}></div>
                            <div class="stream-grid-row" style="flex: {100 - $streamTiles.verticalSplit};">
                                <div class="stream-tile-cell" style="flex: {$streamTiles.horizontalSplit};">
                                    {#if tiledStreams[1]}
                                        <StreamPlayer stream={tiledStreams[1]} showClose={true} />
                                    {:else}
                                        <div class="stream-tile-wrapper empty-tile">
                                            <div class="empty-tile-content">Add stream from terminal</div>
                                        </div>
                                    {/if}
                                </div>
                                <div class="resize-divider-h" class:dragging={isDraggingH} on:mousedown={startHorizontalDrag}></div>
                                <div class="stream-tile-cell" style="flex: {100 - $streamTiles.horizontalSplit};">
                                    {#if tiledStreams[2]}
                                        <StreamPlayer stream={tiledStreams[2]} showClose={true} />
                                    {:else}
                                        <div class="stream-tile-wrapper empty-tile">
                                            <div class="empty-tile-content">Add stream from terminal</div>
                                        </div>
                                    {/if}
                                </div>
                            </div>
                        {/if}
                    </div>
                {:else}
                    <!-- Single stream layout -->
                    <div class="player-area">
                        <div class="dummy-player"></div>
                        <div class="player-container">
                            <div id="player"></div>
                        </div>
                        {#if !stats.isLive && !isStreaming && !playerPlaying && !playerInitializing && !playerBuffering}
                            <div class="offline-image-overlay">
                                {#if realm.offlineImageUrl}
                                    <img src={realm.offlineImageUrl} alt="Stream offline" />
                                {:else}
                                    <div class="offline-placeholder">
                                        <div class="offline-icon">⏸</div>
                                        <div class="offline-text">{realm.name}</div>
                                    </div>
                                {/if}
                                <div class="offline-badge">OFFLINE</div>
                            </div>
                        {/if}
                    </div>
                {/if}
            </div>
            
            <div class="stream-info-section" style="--user-color: {realm.colorCode || '#561D5E'}">
                <div class="stream-header">
                    <div class="header-top">
                        <h1 style="color: {realm.titleColor || '#ffffff'};">{realm.name}</h1>
                        <div class="live-status-badge" class:live={stats.isLive}>
                            <span class="badge-segment">{stats.isLive ? stats.connections : realm.viewerCount} viewers</span>
                            {#if stats.isLive && stats.bitrate > 0}
                                <span class="badge-divider"></span>
                                <span class="badge-segment">{formatBitrate(stats.bitrate)}</span>
                            {/if}
                            {#if stats.isLive && durationDisplay}
                                <span class="badge-divider"></span>
                                <span class="badge-segment">{durationDisplay}</span>
                            {/if}
                            <span class="badge-divider"></span>
                            <span class="badge-segment status" class:live={stats.isLive}>
                                {stats.isLive ? 'LIVE' : 'Offline'}
                            </span>
                        </div>
                    </div>

                    <div class="streamer-info">
                        <div
                            class="streamer-avatar"
                            class:has-color={realm.colorCode}
                            class:with-image={realm.avatarUrl}
                            style="--user-color: {realm.colorCode || '#561D5E'}"
                        >
                            {#if realm.avatarUrl}
                                <img src={realm.avatarUrl} alt={realm.username} />
                            {:else}
                                {realm.username?.charAt(0).toUpperCase() || '?'}
                            {/if}
                        </div>
                        <div class="streamer-details">
                            <a href="/profile/{realm.username}" class="streamer-name">{realm.username}</a>
                            {#if stats.isLive && stats.resolution !== 'N/A'}
                                <div class="compact-stats">
                                    <span class="stat-compact">{stats.resolution}</span>
                                </div>
                            {/if}
                        </div>
                    </div>

                    {#if realm.description}
                        <div class="stream-description">
                            {realm.description}
                        </div>
                    {/if}
                </div>
            </div>
        </div>
        
        <div class="sidebar">
            <div class="chat-section">
                <ChatPanel realmId={realm.name} userColor={$userColor} chatEnabled={realm.chatEnabled !== false} chatGuestsAllowed={realm.chatGuestsAllowed !== false} />
            </div>
        </div>
    </div>
{/if}

{#if message}
    <div class="message" style="position: fixed; top: 2rem; right: 2rem; padding: 1rem 2rem; background: var(--primary); color: white; border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); z-index: 1000;">
        {message}
    </div>
{/if}