const AnimePlayer = (function() {
    let _animeId = null;
    let _currentEpisode = 0;
    let _entrySource = 'anilist';
    let _audioMode = 'sub';
    let _isLocal = false;
    let _malId = null;
    let _skipBtn = null;
    let _skipIntervals = [];
    let _progressUpdated = false;
    let _animeTitle = "Anime";
    let _rpcActive = false;
    let _rawVideoData = null;
    let _currentSubtitles = [];
    let _localEntryId = null;
    let _totalEpisodes = 0;
    let _manualExtensionId = null;
    let _activeSubtitleIndex = -1;
    let _roomMode = false;
    let _isRoomHost = false;
    let _roomWebSocket = null;

    let hlsInstance = null;
    let subtitleRenderer = null;
    let cursorTimeout = null;
    let settingsPanelActive = false;
    let _settingsView = 'main';

    const els = {
        wrapper: null,
        playerWrapper: null,
        playerContainer: null,
        video: null,
        loader: null,
        loaderText: null,
        serverSelect: null,
        extSelect: null,
        subDubToggle: null,
        epTitle: null,
        prevBtn: null,
        nextBtn: null,
        mpvBtn: null,
        downloadBtn: null,
        downloadModal: null,
        dlQualityList: null,
        dlAudioList: null,
        dlSubsList: null,
        dlConfirmBtn: null,
        dlCancelBtn: null,
        manualMatchBtn: null,

        // Custom Controls
        playPauseBtn: null,
        volumeBtn: null,
        volumeSlider: null,
        timeDisplay: null,
        settingsBtn: null,
        settingsPanel: null,
        fullscreenBtn: null,
        progressContainer: null,
        progressPlayed: null,
        progressBuffer: null,
        progressHandle: null,
        subtitlesCanvas: null
    };

    function init(animeId, initialSource, isLocal, animeData, roomMode = false) {
        _roomMode = roomMode;
        _animeId = animeId;
        _entrySource = initialSource || 'anilist';
        _isLocal = isLocal;
        _totalEpisodes = animeData.episodes || 1000;

        if (animeData.title) {
            _animeTitle = animeData.title.romaji || animeData.title.english || "Anime";
        }

        initElements();
        setupEventListeners();

        if (_roomMode) {
            if(els.playerWrapper) {
                els.playerWrapper.style.display = 'block';
                els.playerWrapper.classList.add('room-mode');
            }
        } else {
            loadExtensionsList();
        }
    }

    function initElements() {
        els.wrapper = document.getElementById('hero-wrapper');
        els.playerWrapper = document.getElementById('player-wrapper');
        els.playerContainer = els.playerWrapper?.querySelector('.player-container');
        els.video = document.getElementById('player');
        els.loader = document.getElementById('player-loading');
        els.loaderText = document.getElementById('player-loading-text');

        // Header controls
        els.downloadBtn = document.getElementById('download-btn');
        els.downloadModal = document.getElementById('download-modal');
        els.dlQualityList = document.getElementById('dl-quality-list');
        els.dlAudioList = document.getElementById('dl-audio-list');
        els.dlSubsList = document.getElementById('dl-subs-list');
        els.dlConfirmBtn = document.getElementById('confirm-dl-btn');
        els.dlCancelBtn = document.getElementById('cancel-dl-btn');
        els.manualMatchBtn = document.getElementById('manual-match-btn');
        els.mpvBtn = document.getElementById('mpv-btn');
        els.serverSelect = document.getElementById('server-select');
        els.extSelect = document.getElementById('extension-select');
        els.subDubToggle = document.getElementById('sd-toggle');
        els.epTitle = document.getElementById('player-episode-title');
        els.prevBtn = document.getElementById('prev-ep-btn');
        els.nextBtn = document.getElementById('next-ep-btn');

        // Custom controls
        els.playPauseBtn = document.getElementById('play-pause-btn');
        els.volumeBtn = document.getElementById('volume-btn');
        els.volumeSlider = document.getElementById('volume-slider');
        els.timeDisplay = document.getElementById('time-display');
        els.settingsBtn = document.getElementById('settings-btn');
        els.settingsPanel = document.getElementById('settings-panel');
        els.fullscreenBtn = document.getElementById('fullscreen-btn');
        els.progressContainer = document.querySelector('.progress-container');
        els.progressPlayed = document.querySelector('.progress-played');
        els.progressBuffer = document.querySelector('.progress-buffer');
        els.progressHandle = document.querySelector('.progress-handle');

        els.subtitlesCanvas = document.getElementById('subtitles-canvas');

        if (!document.getElementById('skip-overlay-btn')) {
            const btn = document.createElement('button');
            btn.id = 'skip-overlay-btn';
            if(els.playerContainer) els.playerContainer.appendChild(btn);
            _skipBtn = btn;
        } else {
            _skipBtn = document.getElementById('skip-overlay-btn');
        }
    }

    function setupEventListeners() {
        if(!_roomMode) {
            const closeBtn = document.getElementById('close-player-btn');
            if(closeBtn) closeBtn.addEventListener('click', closePlayer);
        }

        if(els.prevBtn) els.prevBtn.onclick = () => playEpisode(_currentEpisode - 1);
        if(els.nextBtn) els.nextBtn.onclick = () => playEpisode(_currentEpisode + 1);

        // Skip button
        if(_skipBtn) _skipBtn.onclick = () => handleOverlayClick();

        // Audio mode toggle
        if(els.subDubToggle) els.subDubToggle.addEventListener('click', toggleAudioMode);

        // Server/Extension changes
        if(els.serverSelect) els.serverSelect.addEventListener('change', () => loadStream());
        if(els.extSelect) els.extSelect.addEventListener('change', () => handleExtensionChange(true));

        // Manual match
        if (els.manualMatchBtn) {
            els.manualMatchBtn.addEventListener('click', openMatchModal);
        }

        // Download
        if (els.downloadBtn) {
            els.downloadBtn.addEventListener('click', downloadEpisode);
        }
        if (els.dlConfirmBtn) els.dlConfirmBtn.onclick = executeDownload;
        if (els.dlCancelBtn) els.dlCancelBtn.onclick = closeDownloadModal;
        const closeDlModalBtn = document.getElementById('close-download-modal');
        if (closeDlModalBtn) closeDlModalBtn.onclick = closeDownloadModal;
        if (els.downloadModal) {
            els.downloadModal.addEventListener('click', (e) => {
                if (e.target === els.downloadModal) closeDownloadModal();
            });
        }

        // MPV
        if(els.mpvBtn) els.mpvBtn.addEventListener('click', openInMPV);

        // Custom controls
        setupCustomControls();

        // Cursor management
        setupCursorManagement();

        // Keyboard shortcuts
        setupKeyboardShortcuts();
    }

    function loadVideoFromRoom(videoData) {
        console.log('AnimePlayer.loadVideoFromRoom called with:', videoData);

        if (!videoData || !videoData.url) {
            console.error('Invalid video data provided to loadVideoFromRoom');
            return;
        }

        if (videoData.malId) _malId = videoData.malId;
        if (videoData.episode) _currentEpisode = parseInt(videoData.episode);

        _skipIntervals = [];
        if (els.progressContainer) {
            els.progressContainer.querySelectorAll('.skip-range, .skip-cut').forEach(e => e.remove());
        }
        if (_skipBtn) _skipBtn.classList.remove('visible');

        _currentSubtitles = videoData.subtitles || [];

        if (els.loader) els.loader.style.display = 'none';

        initVideoPlayer(videoData.url, videoData.type || 'm3u8', videoData.subtitles || []);
    }

    function setupCustomControls() {
        // ELIMINADO: if (_roomMode && !_isRoomHost) return;
        // Ahora permitimos que el código fluya para habilitar volumen y ajustes a todos

        // 1. Play/Pause (SOLO HOST)
        if(els.playPauseBtn) {
            els.playPauseBtn.onclick = togglePlayPause; // La validación de permiso se hará dentro de togglePlayPause
        }
        if(els.video) {
            els.video.onclick = togglePlayPause; // Click en video para pausar
            els.video.ondblclick = toggleFullscreen; // Doble click siempre permitido
        }

        // 2. Volume (TODOS)
        if(els.volumeBtn) {
            els.volumeBtn.onclick = toggleMute;
        }
        if(els.volumeSlider) {
            els.volumeSlider.oninput = (e) => {
                setVolume(e.target.value / 100);
            };
        }

        // 3. Settings (TODOS - Aquí están los subtítulos y audio)
        if(els.settingsBtn) {
            els.settingsBtn.onclick = (e) => {
                e.stopPropagation();
                settingsPanelActive = !settingsPanelActive;
                if (settingsPanelActive) {
                    _settingsView = 'main';
                    buildSettingsPanel();
                    els.settingsPanel?.classList.add('active');
                } else {
                    els.settingsPanel?.classList.remove('active');
                }
            };
        }

        // Close settings when clicking outside (TODOS)
        document.onclick = (e) => {
            if (settingsPanelActive && els.settingsPanel &&
                !els.settingsPanel.contains(e.target) &&
                !els.settingsBtn.contains(e.target)) {
                settingsPanelActive = false;
                els.settingsPanel.classList.remove('active');
            }
        };

        // 4. Fullscreen (TODOS)
        if(els.fullscreenBtn) {
            els.fullscreenBtn.onclick = toggleFullscreen;
        }

        // 5. Progress bar (SOLO HOST para buscar, TODOS para ver)
        if(els.progressContainer) {
            // El listener se añade, pero seekToPosition bloqueará a los invitados
            els.progressContainer.onclick = seekToPosition;
        }

        // 6. Video events (TODOS - Necesarios para actualizar la UI localmente)
        if(els.video) {
            els.video.onplay = onPlay;
            els.video.onpause = onPause;
            els.video.ontimeupdate = onTimeUpdate;
            els.video.onprogress = onProgress;
            els.video.onloadedmetadata = onLoadedMetadata;
            els.video.onended = onEnded;
            els.video.onvolumechange = onVolumeChange;
            els.video.onseeked = onSeeked;
        }
    }

    function setupCursorManagement() {
        if (!els.playerContainer) return;

        const showCursor = () => {
            els.playerContainer.classList.add('show-cursor');
            clearTimeout(cursorTimeout);
            if (!els.video?.paused) {
                cursorTimeout = setTimeout(() => {
                    els.playerContainer.classList.remove('show-cursor');
                }, 3000);
            }
        };

        els.playerContainer.addEventListener('mousemove', showCursor);
        els.playerContainer.addEventListener('mouseenter', showCursor);

        els.video?.addEventListener('pause', () => {
            clearTimeout(cursorTimeout);
            els.playerContainer.classList.add('show-cursor');
        });

        els.video?.addEventListener('play', () => {
            showCursor();
        });
    }

    function setupKeyboardShortcuts() {
        document.addEventListener('keydown', (e) => {
            if (!els.playerWrapper || els.playerWrapper.style.display === 'none') return;

            if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;

            // En room mode, solo el host puede usar shortcuts de control
            if (_roomMode && !_isRoomHost) {
                // Permitir fullscreen y volumen para todos
                if (e.key.toLowerCase() === 'f') {
                    e.preventDefault();
                    toggleFullscreen();
                } else if (e.key.toLowerCase() === 'm') {
                    e.preventDefault();
                    toggleMute();
                } else if (e.key === 'ArrowUp') {
                    e.preventDefault();
                    adjustVolume(0.1);
                } else if (e.key === 'ArrowDown') {
                    e.preventDefault();
                    adjustVolume(-0.1);
                }
                return;
            }

            switch(e.key.toLowerCase()) {
                case ' ':
                case 'k':
                    e.preventDefault();
                    togglePlayPause();
                    break;
                case 'f':
                    e.preventDefault();
                    toggleFullscreen();
                    break;
                case 'm':
                    e.preventDefault();
                    toggleMute();
                    break;
                case 'arrowleft':
                    e.preventDefault();
                    seekRelative(-10);
                    break;
                case 'arrowright':
                    e.preventDefault();
                    seekRelative(10);
                    break;
                case 'j':
                    e.preventDefault();
                    seekRelative(-10);
                    break;
                case 'l':
                    e.preventDefault();
                    seekRelative(10);
                    break;
                case 'arrowup':
                    e.preventDefault();
                    adjustVolume(0.1);
                    break;
                case 'arrowdown':
                    e.preventDefault();
                    adjustVolume(-0.1);
                    break;
                case 'n':
                    e.preventDefault();
                    if (_currentEpisode < _totalEpisodes) playEpisode(_currentEpisode + 1);
                    break;
                case 'p':
                    e.preventDefault();
                    if (_currentEpisode > 1) playEpisode(_currentEpisode - 1);
                    break;
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    e.preventDefault();
                    const percent = parseInt(e.key) / 10;
                    seekToPercent(percent);
                    break;
            }
        });
    }

    // Control functions
    function togglePlayPause() {
        if (_roomMode && !_isRoomHost && !hasControlPermission()) {
            showPermissionToast('You need playback control permission');
            return;
        }

        if (!els.video) return;

        if (els.video.paused) {
            els.video.play().catch(() => {});

            if (_roomMode && (_isRoomHost || hasControlPermission())) {
                sendRoomEvent('play', { currentTime: els.video.currentTime });
            }
        } else {
            els.video.pause();

            if (_roomMode && (_isRoomHost || hasControlPermission())) {
                sendRoomEvent('pause', { currentTime: els.video.currentTime });
            }
        }
    }

    function toggleMute() {
        if (!els.video) return;
        els.video.muted = !els.video.muted;
    }

    function setVolume(vol) {
        if (!els.video) return;
        els.video.volume = Math.max(0, Math.min(1, vol));
        els.video.muted = vol === 0;
    }

    function adjustVolume(delta) {
        if (!els.video) return;
        setVolume(els.video.volume + delta);
        if (els.volumeSlider) {
            els.volumeSlider.value = els.video.volume * 100;
        }
    }

    function toggleFullscreen() {
        if (!document.fullscreenElement && !document.webkitFullscreenElement) {
            const elem = els.playerContainer || els.playerWrapper;
            if (elem.requestFullscreen) {
                elem.requestFullscreen();
            } else if (elem.webkitRequestFullscreen) {
                elem.webkitRequestFullscreen();
            }
        } else {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            }
        }
    }

    function seekToPosition(e) {
        if (!els.video || !els.progressContainer) return;
        if (_roomMode && !_isRoomHost && !hasControlPermission()) return;

        const rect = els.progressContainer.getBoundingClientRect();
        const pos = (e.clientX - rect.left) / rect.width;
        const newTime = pos * els.video.duration;

        els.video.currentTime = newTime;

        if (_roomMode && (_isRoomHost || hasControlPermission())) {
            sendRoomEvent('seek', { currentTime: newTime });
        }
    }

    function updateProgressHandle(e) {
        if (!els.progressHandle || !els.progressContainer) return;
        const rect = els.progressContainer.getBoundingClientRect();
        const pos = (e.clientX - rect.left) / rect.width;
        els.progressHandle.style.left = `${pos * 100}%`;
    }


    function seekRelative(seconds) {
        if (!els.video) return;
        if (_roomMode && !_isRoomHost && !hasControlPermission()) {
            showPermissionToast('You need playback control permission');
            return;
        }

        const newTime = Math.max(0, Math.min(els.video.duration, els.video.currentTime + seconds));
        els.video.currentTime = newTime;

        if (_roomMode && (_isRoomHost || hasControlPermission())) {
            sendRoomEvent('seek', { currentTime: newTime });
        }
    }

    function seekToPercent(percent) {
        if (!els.video) return;
        if (_roomMode && !_isRoomHost && !hasControlPermission()) {
            showPermissionToast('You need playback control permission');
            return;
        }
        const newTime = els.video.duration * percent;
        els.video.currentTime = newTime;

        if (_roomMode && (_isRoomHost || hasControlPermission())) {
            sendRoomEvent('seek', { currentTime: newTime });
        }
    }

    function hasControlPermission() {
        return window.__userPermissions?.canControl || false;
    }

    function showPermissionToast(message) {
        const toast = document.createElement('div');
        toast.className = 'permission-toast';
        toast.textContent = message;
        toast.style.cssText = `
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background: rgba(239, 68, 68, 0.95);
        color: white;
        padding: 16px 24px;
        border-radius: 10px;
        font-weight: 600;
        z-index: 10000;
        box-shadow: 0 8px 24px rgba(0,0,0,0.4);
        animation: fadeIn 0.3s ease;
    `;
        document.body.appendChild(toast);

        setTimeout(() => {
            toast.style.animation = 'fadeOut 0.3s ease';
            setTimeout(() => toast.remove(), 300);
        }, 2500);
    }

    // Video event handlers
    function onPlay() {
        if (els.playPauseBtn) {
            els.playPauseBtn.innerHTML = `
                <svg viewBox="0 0 24 24">
                    <path d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"/>
                </svg>
            `;
        }

        if (!els.video.duration) return;
        const elapsed = Math.floor(els.video.currentTime);
        const start = Math.floor(Date.now() / 1000) - elapsed;
        const end = start + Math.floor(els.video.duration);
        sendRPC({ startTimestamp: start, endTimestamp: end });
        _rpcActive = true;
    }

    function onSeeked() {
        if (!els.video || els.video.paused || !els.video.duration) return;

        const elapsed = Math.floor(els.video.currentTime);
        const start = Math.floor(Date.now() / 1000) - elapsed;
        const end = start + Math.floor(els.video.duration);

        sendRPC({ startTimestamp: start, endTimestamp: end });
    }

    function onPause() {
        if (els.playPauseBtn) {
            els.playPauseBtn.innerHTML = `
                <svg viewBox="0 0 24 24">
                    <path d="M8 5v14l11-7z"/>
                </svg>
            `;
        }

        if (_rpcActive) sendRPC({ paused: true });
    }

    function onProgress() {
        if (!els.video || !els.progressBuffer) return;
        if (els.video.buffered.length > 0) {
            const bufferedEnd = els.video.buffered.end(els.video.buffered.length - 1);
            const percent = (bufferedEnd / els.video.duration) * 100;
            els.progressBuffer.style.width = `${percent}%`;
        }
    }

    function onLoadedMetadata() {
        if (els.video) {
            applyAniSkip(_malId, _currentEpisode);
        }
    }

    function onEnded() {
        if (!_roomMode && _currentEpisode < _totalEpisodes) {
            playEpisode(_currentEpisode + 1);
        }
    }

    function onVolumeChange() {
        if (!els.video || !els.volumeBtn || !els.volumeSlider) return;

        const volume = els.video.volume;
        const muted = els.video.muted;

        els.volumeSlider.value = volume * 100;

        let icon;
        if (muted || volume === 0) {
            icon = '<svg viewBox="0 0 24 24"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>';
        } else if (volume < 0.5) {
            icon = '<svg viewBox="0 0 24 24"><path d="M7 9v6h4l5 5V4l-5 5H7z"/></svg>';
        } else {
            icon = '<svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>';
        }

        els.volumeBtn.innerHTML = icon;
    }

    function sendRoomEvent(eventType, data = {}) {
        if (!_roomMode || !_roomWebSocket) return;
        if (!_isRoomHost && !hasControlPermission()) return;

        if (_roomWebSocket.readyState !== WebSocket.OPEN) return;

        console.log('Sending room event:', eventType, data);
        _roomWebSocket.send(JSON.stringify({
            type: eventType,
            ...data
        }));
    }

    function setWebSocket(ws) {
        console.log('Setting WebSocket reference in AnimePlayer');
        _roomWebSocket = ws;
    }

    function formatTime(seconds) {
        if (!isFinite(seconds) || isNaN(seconds)) return '0:00';
        const h = Math.floor(seconds / 3600);
        const m = Math.floor((seconds % 3600) / 60);
        const s = Math.floor(seconds % 60);
        if (h > 0) {
            return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
        }
        return `${m}:${s.toString().padStart(2, '0')}`;
    }

    const Icons = {
        back: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>`,
        check: `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>`,
        chevron: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"></polyline></svg>`,
        quality: `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 8-8 8 8 0 0 1-8 8z"></path><path d="M14.31 8l5.74 9.94"></path><path d="M9.69 8h11.48"></path><path d="M7.38 12l5.74-9.94"></path><path d="M9.69 16L3.95 6.06"></path><path d="M14.31 16H2.83"></path><path d="M16.62 12l-5.74 9.94"></path></svg>`,
        audio: `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18V5l12-2v13"></path><circle cx="6" cy="18" r="3"></circle><circle cx="18" cy="16" r="3"></circle></svg>`,
        subs: `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>`,
        speed: `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`
    };

    function buildSettingsPanel() {
        if (!els.settingsPanel) return;

        els.settingsPanel.innerHTML = '';

        if (_settingsView === 'main') {
            buildMainMenu();
        } else {
            buildSubMenu(_settingsView);
        }
    }

    function buildMainMenu() {
        let html = `<div class="settings-content">`;

        // 1. Quality
        if (hlsInstance && hlsInstance.levels && hlsInstance.levels.length > 1) {
            const currentLevel = hlsInstance.currentLevel;
            const label = currentLevel === -1 ? 'Auto' : (hlsInstance.levels[currentLevel]?.height + 'p');
            html += createMenuItem('quality', 'Quality', label, Icons.quality);
        }

        // 2. Audio
        if (hlsInstance && hlsInstance.audioTracks && hlsInstance.audioTracks.length > 1) {
            const currentAudio = hlsInstance.audioTrack;
            const track = hlsInstance.audioTracks[currentAudio];
            const label = track ? (track.name || track.lang || `Track ${currentAudio + 1}`) : 'Default';
            html += createMenuItem('audio', 'Audio', label, Icons.audio);
        }

        // 3. Subtitles
        if (_currentSubtitles && _currentSubtitles.length > 0) {
            let label = 'Off';
            const activeIndex = getActiveSubtitleIndex();
            if (activeIndex !== -1 && _currentSubtitles[activeIndex]) {
                label = _currentSubtitles[activeIndex].label || _currentSubtitles[activeIndex].language;
            }
            html += createMenuItem('subtitle', 'Subtitles', label, Icons.subs);
        }

        // 4. Playback Speed
        if (els.video && (!_roomMode || _isRoomHost)) {
            const label = els.video.playbackRate === 1 ? 'Normal' : `${els.video.playbackRate}x`;
            html += createMenuItem('speed', 'Playback Speed', label, Icons.speed);
        }

        html += `</div>`;
        els.settingsPanel.innerHTML = html;

        // Listeners del menú principal
        els.settingsPanel.querySelectorAll('.settings-item').forEach(item => {
            item.addEventListener('click', (e) => {
                e.stopPropagation();
                _settingsView = item.dataset.target;
                buildSettingsPanel();
            });
        });
    }

    function createMenuItem(target, title, value, icon) {
        return `
            <div class="settings-item settings-item-main" data-target="${target}">
                <div class="settings-label-left">
                    <span class="settings-label-icon">${icon}</span>
                    <span>${title}</span>
                </div>
                <div class="settings-value-right">
                    <span>${value}</span>
                    ${Icons.chevron}
                </div>
            </div>
        `;
    }

    function buildSubMenu(type) {
        let title = '';
        let content = '';

        if (type === 'quality') {
            title = 'Quality';
            content = renderQualityOptions();
        } else if (type === 'audio') {
            title = 'Audio Track';
            content = renderAudioOptions();
        } else if (type === 'subtitle') {
            title = 'Subtitles';
            content = renderSubtitleOptions();
        } else if (type === 'speed') {
            title = 'Playback Speed';
            content = renderSpeedOptions();
        }

        const html = `
            <div class="settings-header">
                <button class="settings-back-btn">${Icons.back}</button>
                <span class="settings-title">${title}</span>
            </div>
            <div class="settings-content">
                ${content}
            </div>
        `;

        els.settingsPanel.innerHTML = html;

        // Listener para volver atrás
        els.settingsPanel.querySelector('.settings-back-btn').addEventListener('click', (e) => {
            e.stopPropagation();
            _settingsView = 'main';
            buildSettingsPanel();
        });

        // Listeners para opciones CORREGIDO
        els.settingsPanel.querySelectorAll('.settings-item-option').forEach(opt => {
            opt.addEventListener('click', (e) => {
                e.stopPropagation();
                const val = opt.dataset.value;
                applySetting(type, val);
            });
        });
    }

    // Funciones de renderizado de opciones
    function renderQualityOptions() {
        if (!hlsInstance) return '';
        let html = '';

        // Auto option
        const isAuto = hlsInstance.currentLevel === -1;
        html += `<div class="settings-item settings-item-option ${isAuto ? 'selected' : ''}" data-value="-1">
            <span>Auto</span>${isAuto ? Icons.check : ''}
        </div>`;

        // Levels desc
        hlsInstance.levels.forEach((level, i) => {
            const isSelected = hlsInstance.currentLevel === i;
            html += `<div class="settings-item settings-item-option ${isSelected ? 'selected' : ''}" data-value="${i}">
                <span>${level.height}p</span>${isSelected ? Icons.check : ''}
            </div>`;
        });
        return html;
    }

    function renderAudioOptions() {
        if (!hlsInstance) return '';
        let html = '';
        hlsInstance.audioTracks.forEach((track, i) => {
            const isSelected = hlsInstance.audioTrack === i;
            const label = track.name || track.lang || `Audio ${i + 1}`;
            html += `<div class="settings-item settings-item-option ${isSelected ? 'selected' : ''}" data-value="${i}">
                <span>${label}</span>${isSelected ? Icons.check : ''}
            </div>`;
        });
        return html;
    }

    function renderSubtitleOptions() {
        let html = '';
        const activeIdx = getActiveSubtitleIndex();

        // Off
        html += `<div class="settings-item settings-item-option ${activeIdx === -1 ? 'selected' : ''}" data-value="-1">
            <span>Off</span>${activeIdx === -1 ? Icons.check : ''}
        </div>`;

        _currentSubtitles.forEach((sub, i) => {
            const isSelected = activeIdx === i;
            html += `<div class="settings-item settings-item-option ${isSelected ? 'selected' : ''}" data-value="${i}">
                <span>${sub.label || sub.language}</span>${isSelected ? Icons.check : ''}
            </div>`;
        });
        return html;
    }

    function renderSpeedOptions() {
        const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
        let html = '';
        const currentRate = els.video ? els.video.playbackRate : 1;

        speeds.forEach(speed => {
            const isSelected = Math.abs(currentRate - speed) < 0.1;
            html += `<div class="settings-item settings-item-option ${isSelected ? 'selected' : ''}" data-value="${speed}">
                <span>${speed === 1 ? 'Normal' : speed + 'x'}</span>${isSelected ? Icons.check : ''}
            </div>`;
        });
        return html;
    }

    // Aplicar configuración
    function applySetting(type, value) {
        if (type === 'quality') {
            if (hlsInstance) hlsInstance.currentLevel = parseInt(value);
        } else if (type === 'audio') {
            if (hlsInstance) hlsInstance.audioTrack = parseInt(value);
        } else if (type === 'subtitle') {
            const idx = parseInt(value);
            _activeSubtitleIndex = idx;

            if (els.video && els.video.textTracks) {
                Array.from(els.video.textTracks).forEach((track, i) => {
                    track.mode = 'hidden';
                });
            }

            initSubtitleRenderer();
        } else if (type === 'speed') {
            if (els.video) els.video.playbackRate = parseFloat(value);
        }

        _settingsView = 'main';
        buildSettingsPanel();
    }

    function getActiveSubtitleIndex() {
        return _activeSubtitleIndex;
    }

    async function initSubtitleRenderer() {
        if (!els.video) return;

        // Cleanup previous instance
        if (subtitleRenderer) {
            try {
                subtitleRenderer.dispose();
            } catch(e) {
                console.warn('Error disposing renderer:', e);
            }
            subtitleRenderer = null;
        }

        const activeIdx = getActiveSubtitleIndex();
        if (activeIdx === -1) return;

        const currentSub = _currentSubtitles[activeIdx];
        if (!currentSub) return;

        const src = currentSub.src.toLowerCase();
        const label = (currentSub.label || '').toLowerCase();

        // CASO 1: ASS (Usa JASSUB)
        if (src.endsWith('.ass') || label.includes('ass')) {
            try {
                console.log('Initializing JASSUB for:', currentSub.label);
                if (window.SubtitleRenderer && typeof window.JASSUB !== 'undefined') {
                    subtitleRenderer = new SubtitleRenderer(els.video, els.subtitlesCanvas);
                    await subtitleRenderer.init(currentSub.src);
                }
            } catch (e) {
                console.error('JASSUB setup error:', e);
            }
        }
        // CASO 2: SRT (Usa SimpleSubtitleRenderer)
        else if (src.endsWith('.srt') || label.includes('srt')) {
            try {
                console.log('Initializing Simple Renderer for:', currentSub.label);
                if (window.SimpleSubtitleRenderer) {
                    subtitleRenderer = new SimpleSubtitleRenderer(els.video, els.subtitlesCanvas);
                    await subtitleRenderer.loadSubtitles(currentSub.src);
                }
            } catch (e) {
                console.error('Simple Renderer setup error:', e);
            }
        }
        else {
            console.log('Using native browser rendering for VTT');
        }
    }

    function onTimeUpdate() {
        if (!els.video) return;

        // Update progress bar
        const percent = (els.video.currentTime / els.video.duration) * 100;
        if (els.progressPlayed) {
            els.progressPlayed.style.width = `${percent}%`;
        }
        if (els.progressHandle) {
            els.progressHandle.style.left = `${percent}%`;
        }

        // Update time display
        if (els.timeDisplay) {
            const current = formatTime(els.video.currentTime);
            const total = formatTime(els.video.duration);
            els.timeDisplay.textContent = `${current} / ${total}`;
        }

        // Update progress for AniList
        if (!_roomMode && !_progressUpdated && els.video.duration) {
            const percentage = els.video.currentTime / els.video.duration;
            if (percentage >= 0.8) {
                updateProgress();
                _progressUpdated = true;
            }
        }
    }

    // Player lifecycle
    async function playEpisode(episodeNumber) {
        const targetEp = parseInt(episodeNumber);
        if (targetEp < 1 || targetEp > _totalEpisodes) return;

        _currentEpisode = targetEp;
        _progressUpdated = false;

        if(els.epTitle) els.epTitle.innerText = `Episode ${targetEp}`;
        if(els.prevBtn) els.prevBtn.disabled = (_currentEpisode <= 1);
        if(els.nextBtn) els.nextBtn.disabled = (_currentEpisode >= _totalEpisodes);

        if(_skipBtn) {
            _skipBtn.classList.remove('visible');
            _skipBtn.classList.remove('is-next');
        }

        const newUrl = new URL(window.location);
        newUrl.searchParams.set('episode', targetEp);
        window.history.pushState({}, '', newUrl);

        if(els.playerWrapper) els.playerWrapper.style.display = 'block';
        document.body.classList.add('stop-scrolling');

        const trailer = document.querySelector('#trailer-player iframe');
        if(trailer) trailer.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');

        _rpcActive = false;
        setLoading("Checking availability...");

        let shouldPlayLocal = false;
        try {
            const check = await fetch(`/api/library/${_animeId}/units`);
            const data = await check.json();
            const localUnit = data.units ? data.units.find(u => u.number === targetEp) : null;

            if (localUnit && els.extSelect.value === 'local') {
                shouldPlayLocal = true;
            }
        } catch (e) {
            console.warn("Availability check failed:", e);
            shouldPlayLocal = (els.extSelect.value === 'local');
        }

        if (els.manualMatchBtn) {
            els.manualMatchBtn.style.display = shouldPlayLocal ? 'none' : 'flex';
        }

        if (shouldPlayLocal) {
            let localOption = els.extSelect.querySelector('option[value="local"]');
            if (!localOption) {
                localOption = document.createElement('option');
                localOption.value = 'local';
                localOption.innerText = 'Local';
                els.extSelect.appendChild(localOption);
            }
            els.extSelect.value = 'local';
            if(els.subDubToggle) els.subDubToggle.style.display = 'none';
            if(els.serverSelect) els.serverSelect.style.display = 'none';
            loadStream();
        } else {
            if (els.extSelect.value === 'local') {
                const localOption = els.extSelect.querySelector('option[value="local"]');
                if (localOption) localOption.remove();

                let fallbackSource = (_entrySource !== 'local') ? _entrySource : 'anilist';
                if (!els.extSelect.querySelector(`option[value="${fallbackSource}"]`)) {
                    if (els.extSelect.options.length > 0) {
                        fallbackSource = els.extSelect.options[0].value;
                    }
                }
                els.extSelect.value = fallbackSource;
                handleExtensionChange(true);
            } else {
                if (els.serverSelect.options.length === 0) {
                    handleExtensionChange(true);
                } else {
                    loadStream();
                }
            }
        }
    }

    function closePlayer() {
        if (hlsInstance) {
            hlsInstance.destroy();
            hlsInstance = null;
        }

        if (subtitleRenderer) {
            try { subtitleRenderer.dispose(); } catch(e) {}
            subtitleRenderer = null;
        }

        // Stop video
        if (els.video) {
            els.video.pause();
            els.video.removeAttribute('src');
            els.video.load();
        }

        if(els.playerWrapper) els.playerWrapper.style.display = 'none';
        document.body.classList.remove('stop-scrolling');
        _skipIntervals = [];
        _rpcActive = false;

        sendRPC({ paused: true });

        const newUrl = new URL(window.location);
        newUrl.searchParams.delete('episode');
        window.history.pushState({}, '', newUrl);

        const trailer = document.querySelector('#trailer-player iframe');
        if(trailer) {
            trailer.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
        }
    }

    async function loadExtensionsList() {
        try {
            const res = await fetch('/api/extensions/anime');
            const data = await res.json();
            const extensions = data.extensions || [];

            if (_isLocal && !extensions.includes('local')) extensions.push('local');

            els.extSelect.innerHTML = '';
            extensions.forEach(ext => {
                const opt = document.createElement('option');
                opt.value = ext;
                opt.innerText = ext.charAt(0).toUpperCase() + ext.slice(1);
                els.extSelect.appendChild(opt);
            });

            if (extensions.includes(_entrySource)) {
                els.extSelect.value = _entrySource;
            } else if (extensions.length > 0) {
                els.extSelect.value = extensions[0];
            }

            if (els.extSelect.value === 'local') {
                els.subDubToggle.style.display = 'none';
                els.serverSelect.style.display = 'none';
            } else if (els.extSelect.value) {
                handleExtensionChange(false);
            }
        } catch (e) { console.error("Error loading extensions:", e); }
    }

    async function handleExtensionChange(shouldPlay = true) {
        const selectedExt = els.extSelect.value;
        if (els.manualMatchBtn) {
            els.manualMatchBtn.style.display = (selectedExt === 'local') ? 'none' : 'flex';
        }

        if (selectedExt === 'local') {
            els.subDubToggle.style.display = 'none';
            els.serverSelect.style.display = 'none';
            if (shouldPlay && _currentEpisode > 0) loadStream();
            return;
        }

        _manualExtensionId = null;
        setLoading("Loading Extension Settings...");

        try {
            const res = await fetch(`/api/extensions/${selectedExt}/settings`);
            const settings = await res.json();

            els.subDubToggle.style.display = settings.supportsDub ? 'flex' : 'none';
            setAudioMode('sub');

            els.serverSelect.innerHTML = '';
            if (settings.episodeServers && settings.episodeServers.length > 0) {
                settings.episodeServers.forEach(srv => {
                    const opt = document.createElement('option');
                    opt.value = srv;
                    opt.innerText = srv;
                    els.serverSelect.appendChild(opt);
                });
                els.serverSelect.value = settings.episodeServers[0];
                els.serverSelect.style.display = 'block';
            } else {
                els.serverSelect.style.display = 'none';
            }

            if (shouldPlay && _currentEpisode > 0) {
                loadStream();
            } else {
                if(els.loader) els.loader.style.display = 'none';
            }
        } catch (error) {
            console.error("Failed to load settings:", error);
            setLoading("Failed to load extension settings.");
        }
    }

    function toggleAudioMode() {
        _audioMode = _audioMode === 'sub' ? 'dub' : 'sub';
        setAudioMode(_audioMode);
        loadStream();
    }

    function setAudioMode(mode) {
        _audioMode = mode;
        els.subDubToggle.setAttribute('data-state', mode);
        document.getElementById('opt-sub').classList.toggle('active', mode === 'sub');
        document.getElementById('opt-dub').classList.toggle('active', mode === 'dub');
    }

    function setLoading(msg) {
        if(els.loaderText) els.loaderText.innerText = msg;
        if(els.loader) els.loader.style.display = 'flex';
    }

    async function loadStream() {
        if (!_currentEpisode) return;
        _progressUpdated = false;
        setLoading("Fetching Stream...");

        _rawVideoData = null;
        _currentSubtitles = [];

        // Cleanup before fetch to prevent ghost events
        if (hlsInstance) {
            hlsInstance.destroy();
            hlsInstance = null;
        }

        if (subtitleRenderer) {
            try { subtitleRenderer.dispose(); } catch(e) {}
            subtitleRenderer = null;
        }

        const currentExt = els.extSelect.value;

        if (currentExt !== 'local') {
            _isLocal = false;
            _rawVideoData = null;
        }

        // En la función loadStream(), cuando detectas local:

        if (currentExt === 'local') {
            try {
                setLoading("Fetching Local Unit Data...");

                // 1. Obtener unidades
                const unitsRes = await fetch(`/api/library/${_animeId}/units`);
                if (!unitsRes.ok) throw new Error("Could not fetch local units");

                const unitsData = await unitsRes.json();
                _localEntryId = unitsData.entry_id;

                const targetUnit = unitsData.units ?
                    unitsData.units.find(u => u.number === parseInt(_currentEpisode)) : null;

                if (!targetUnit) {
                    throw new Error(`Episode ${_currentEpisode} not found in local library`);
                }

                setLoading("Initializing HLS Stream...");

                // 2. Obtener Manifest
                const manifestRes = await fetch(
                    `/api/library/stream/anime/${unitsData.entry_id}/${targetUnit.number}/manifest`
                );

                if (!manifestRes.ok) throw new Error("Failed to generate stream manifest");

                const manifestData = await manifestRes.json();

                // DEBUG: Verificar que llega aquí
                console.log("Manifest Loaded:", manifestData);

                // 3. Chapters
                if (manifestData.chapters && manifestData.chapters.length > 0) {
                    _skipIntervals = manifestData.chapters.map(c => ({
                        startTime: c.start,
                        endTime: c.end,
                        type: (c.title || '').toLowerCase().includes('op') ? 'op' :
                            (c.title || '').toLowerCase().includes('ed') ? 'ed' : 'chapter'
                    }));
                    renderSkipMarkers(_skipIntervals);
                    monitorSkipButton(_skipIntervals);
                }

                // 4. CORRECCIÓN DE SUBTÍTULOS
                const rawSubs = manifestData.subtitles || [];
                console.log("Raw Subtitles from JSON:", rawSubs);

                const subs = rawSubs.map((s, index) => {
                    // Limpieza segura del código de idioma (ej. "English" -> "en")
                    let langCode = 'en';
                    if (s.language && typeof s.language === 'string' && s.language.length >= 2) {
                        langCode = s.language.substring(0, 2).toLowerCase();
                    }

                    // Título legible (Prioridad: Title > Language > Track #)
                    const label = s.title || s.language || `Track ${index + 1}`;

                    return {
                        label: label,
                        srclang: langCode,
                        src: s.url // Usamos la URL directa del JSON local
                    };
                });

                // ACTUALIZACIÓN CRÍTICA DEL ESTADO GLOBAL
                _currentSubtitles = subs;
                console.log("Processed Subtitles:", _currentSubtitles);

                _rawVideoData = {
                    url: manifestData.masterPlaylist,
                    headers: {}
                };

                // Inicializar video pasando explícitamente los subs procesados
                initVideoPlayer(manifestData.masterPlaylist, 'm3u8', subs);

            } catch(e) {
                console.error("Local HLS Error:", e);
                setLoading("Local Error: " + e.message);

                // Fallback logic...
                const localOption = els.extSelect.querySelector('option[value="local"]');
                if (localOption) localOption.remove();
                const fallbackSource = (_entrySource === 'local') ? 'anilist' : _entrySource;
                els.extSelect.value = fallbackSource;
                handleExtensionChange(true);
            }
            return;
        }

        const server = els.serverSelect.value || "";
        const extParam = `&ext=${currentExt}`;
        const realSource = _entrySource === 'local' ? 'anilist' : _entrySource;

        let url = `/api/watch/stream?animeId=${_animeId}` +
            `&episode=${_currentEpisode}` +
            `&server=${encodeURIComponent(server)}` +
            `&category=${_audioMode}` +
            `${extParam}` +
            `&source=${realSource}`;

        if (_manualExtensionId) {
            url += `&extensionAnimeId=${encodeURIComponent(_manualExtensionId)}`;
        }

        try {
            const res = await fetch(url);
            const data = await res.json();

            if (data.error || !data.videoSources?.length) {
                setLoading(data.error || "No sources found.");
                return;
            }

            const source = data.videoSources.find(s => s.type === 'm3u8') || data.videoSources[0];
            const headers = data.headers || {};

            _rawVideoData = {
                url: source.url,
                headers: headers
            };

            let proxyUrl = `/api/proxy?url=${encodeURIComponent(source.url)}`;
            if (headers['Referer'] && headers['Referer'] !== "null") {
                proxyUrl += `&referer=${encodeURIComponent(headers['Referer'])}`;
            }
            if (headers['User-Agent']) {
                proxyUrl += `&userAgent=${encodeURIComponent(headers['User-Agent'])}`;
            }

            const subtitles = (source.subtitles || []).map(sub => ({
                label: sub.language,
                srclang: sub.language.toLowerCase().slice(0, 2),
                src: `/api/proxy?url=${encodeURIComponent(sub.url)}`
            }));

            _currentSubtitles = (source.subtitles || []).map(sub => ({
                label: sub.language,
                srclang: sub.id,
                src: sub.url
            }));

            initVideoPlayer(proxyUrl, source.type, subtitles);
        } catch (err) {
            setLoading("Stream Error: " + err.message);
            console.error(err);
        }
    }

    function initVideoPlayer(url, type, subtitles = []) {
        console.log('initVideoPlayer called:', { url, type, subtitles });

        // 1. CLEANUP FIRST
        if (subtitleRenderer) {
            try {
                subtitleRenderer.dispose();
            } catch(e) {
                console.warn('Renderer dispose error (clean):', e);
            }
            subtitleRenderer = null;
        }

        if (hlsInstance) {
            hlsInstance.destroy();
            hlsInstance = null;
        }

        const container = document.querySelector('.video-frame');
        if (!container) {
            console.error('Video frame container not found!');
            return;
        }

        // 2. Remove OLD Elements
        const oldVideo = container.querySelector('video');
        const oldCanvas = container.querySelector('#subtitles-canvas');

        if (oldVideo) {
            oldVideo.removeAttribute('src');
            oldVideo.load();
            oldVideo.remove();
        }
        if (oldCanvas) {
            oldCanvas.remove();
        }

        // 3. Create NEW Elements - CANVAS FIRST, then VIDEO
        const newCanvas = document.createElement('canvas');
        newCanvas.id = 'subtitles-canvas';

        const newVideo = document.createElement('video');
        newVideo.id = 'player';
        newVideo.crossOrigin = 'anonymous';
        newVideo.playsInline = true;

        container.appendChild(newCanvas);
        container.appendChild(newVideo);

        els.video = newVideo;
        els.subtitlesCanvas = newCanvas;

        console.log('Video and canvas elements created:', { video: els.video, canvas: els.subtitlesCanvas });

        // Re-setup controls with new video element
        setupCustomControls();

        // Hide loader
        if (els.loader) els.loader.style.display = 'none';

        // 4. Initialize Player
        if (Hls.isSupported() && type === 'm3u8') {
            console.log('Initializing HLS player');

            hlsInstance = new Hls({
                enableWorker: true,
                lowLatencyMode: false,
                backBufferLength: 90,
                debug: false
            });

            hlsInstance.on(Hls.Events.ERROR, (event, data) => {
                console.error('HLS Error:', data);
                if (data.fatal) {
                    if (els.loader) {
                        els.loader.style.display = 'flex';
                        if (els.loaderText) els.loaderText.textContent = 'Stream error: ' + (data.details || 'Unknown');
                    }
                }
            });

            hlsInstance.attachMedia(els.video);

            hlsInstance.on(Hls.Events.MEDIA_ATTACHED, () => {
                console.log('HLS media attached, loading source:', url);
                hlsInstance.loadSource(url);
            });

            hlsInstance.on(Hls.Events.MANIFEST_PARSED, () => {
                console.log('HLS manifest parsed, attaching subtitles');
                attachSubtitles(subtitles);
                buildSettingsPanel();

                if (els.downloadBtn && !_roomMode) els.downloadBtn.style.display = 'flex';

                // --- FIX: Inicializar el renderizador de subtítulos para HLS ---
                if (els.video.readyState >= 1) {
                    initSubtitleRenderer();
                } else {
                    els.video.addEventListener('loadedmetadata', () => {
                        initSubtitleRenderer();
                    }, { once: true });
                }
                // -------------------------------------------------------------

                console.log('Attempting to play video');
                els.video.play().catch(err => {
                    console.error('Play error:', err);
                });
            });

            hlsInstance.on(Hls.Events.LEVEL_SWITCHED, () => buildSettingsPanel());
            hlsInstance.on(Hls.Events.AUDIO_TRACK_SWITCHED, () => buildSettingsPanel());

        } else {
            console.log('Using native video player');
            els.video.src = url;
            attachSubtitles(subtitles);
            buildSettingsPanel();

            els.video.addEventListener('loadedmetadata', () => {
                console.log('Video metadata loaded');
                initSubtitleRenderer();
            }, { once: true });

            console.log('Attempting to play video');
            els.video.play().catch(err => {
                console.error('Play error:', err);
            });

            if (els.downloadBtn && !_roomMode) els.downloadBtn.style.display = 'flex';
        }
    }

    function attachSubtitles(subtitles) {
        if (!els.video) return;

        _activeSubtitleIndex = -1;

        Array.from(els.video.querySelectorAll('track')).forEach(t => t.remove());

        if (subtitles.length === 0) return;

        subtitles.forEach((sub, i) => {
            const track = document.createElement('track');
            track.kind = 'subtitles';
            track.label = sub.label;
            track.srclang = sub.srclang;
            track.src = sub.src;
            track.default = i === 0;
            els.video.appendChild(track);
        });

        setTimeout(() => {
            if (els.video.textTracks && els.video.textTracks.length > 0) {
                _activeSubtitleIndex = 0;

                if (!subtitleRenderer) {
                    els.video.textTracks[0].mode = 'showing';
                } else {
                    els.video.textTracks[0].mode = 'hidden';
                }
            }
        }, 100);
    }

    // AniSkip integration
    async function applyAniSkip(malId, episodeNumber) {
        if (!malId || !els.video) return;

        const duration = await waitForDuration(els.video);

        try {
            const url = `https://api.aniskip.com/v2/skip-times/${malId}/${episodeNumber}` +
                `?types[]=op&types[]=ed&episodeLength=${Math.floor(duration)}`;
            const res = await fetch(url);
            if (!res.ok) return;
            const data = await res.json();
            if (!data.found) return;

            _skipIntervals = data.results.map(item => ({
                startTime: item.interval.startTime,
                endTime: item.interval.endTime,
                type: item.skipType
            }));

            renderSkipMarkers(_skipIntervals);
            monitorSkipButton(_skipIntervals);
        } catch (e) {
            console.error('AniSkip Error:', e);
        }
    }

    function waitForDuration(video) {
        return new Promise(resolve => {
            if (video.duration && video.duration > 0) return resolve(video.duration);
            const check = () => {
                if (video.duration && video.duration > 0) {
                    video.removeEventListener('loadedmetadata', check);
                    resolve(video.duration);
                }
            };
            video.addEventListener('loadedmetadata', check);
        });
    }

    function renderSkipMarkers(intervals) {
        if (!els.progressContainer || !els.video.duration) return;
        els.progressContainer.querySelectorAll('.skip-range, .skip-cut').forEach(e => e.remove());

        intervals.forEach(skip => {
            const startPct = (skip.startTime / els.video.duration) * 100;
            const endPct = (skip.endTime / els.video.duration) * 100;

            const range = document.createElement('div');
            range.className = `skip-range ${skip.type}`;
            range.style.left = `${startPct}%`;
            range.style.width = `${endPct - startPct}%`;
            els.progressContainer.appendChild(range);

            createCut(startPct);
            createCut(endPct);
        });
    }

    function createCut(percent) {
        if (percent < 0.5 || percent > 99.5) return;

        const cut = document.createElement('div');
        cut.className = 'skip-cut';
        cut.style.left = `${percent}%`;
        els.progressContainer.appendChild(cut);
    }

    function monitorSkipButton(intervals) {
        if (!_skipBtn || !els.video) return;

        const checkTime = () => {
            const ct = els.video.currentTime;
            const duration = els.video.duration;
            const activeInterval = intervals.find(i => ct >= i.startTime && ct <= i.endTime);

            if (activeInterval) {
                if (activeInterval.type === 'op') {
                    showSkipButton('Skip Intro', activeInterval.endTime, false);
                    return;
                } else if (activeInterval.type === 'ed') {
                    if (_currentEpisode < _totalEpisodes) {
                        showSkipButton('Next Episode', null, true);
                    } else {
                        showSkipButton('Skip Ending', activeInterval.endTime, false);
                    }
                    return;
                }
            }

            if (_currentEpisode < _totalEpisodes && (duration - ct) < 90 && (duration - ct) > 0) {
                if (!activeInterval) {
                    showSkipButton('Next Episode', null, true);
                    return;
                }
            }

            _skipBtn.classList.remove('visible');
        };

        els.video.addEventListener('timeupdate', checkTime);
    }

    function showSkipButton(text, seekTime, isNextAction) {
        if (!_skipBtn) return;
        _skipBtn.innerHTML = `${text} <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M13 17l5-5-5-5M6 17l5-5-5-5"/></svg>`;
        if (isNextAction) {
            _skipBtn.classList.add('is-next');
            _skipBtn.dataset.seekTo = '';
        } else {
            _skipBtn.classList.remove('is-next');
            _skipBtn.dataset.seekTo = seekTime;
        }
        _skipBtn.classList.add('visible');
    }

    function handleOverlayClick() {
        if (!_skipBtn) return;
        if (_skipBtn.classList.contains('is-next')) {
            playEpisode(_currentEpisode + 1);
        } else if (_skipBtn.dataset.seekTo) {
            els.video.currentTime = parseFloat(_skipBtn.dataset.seekTo);
        }
        _skipBtn.classList.remove('visible');
    }

    // Download functionality
    async function downloadEpisode() {
        if (!_rawVideoData || !_rawVideoData.url) {
            alert("Stream not loaded yet.");
            return;
        }

        const isInFullscreen = document.fullscreenElement || document.webkitFullscreenElement;
        if (isInFullscreen) {
            try {
                if (document.exitFullscreen) {
                    await document.exitFullscreen();
                } else if (document.webkitExitFullscreen) {
                    await document.webkitExitFullscreen();
                }
                await new Promise(resolve => setTimeout(resolve, 100));
            } catch (err) {
                console.warn("Error exiting fullscreen:", err);
            }
        }

        const isM3U8 = hlsInstance && hlsInstance.levels && hlsInstance.levels.length > 0;
        const hasMultipleAudio = hlsInstance && hlsInstance.audioTracks && hlsInstance.audioTracks.length > 1;
        const hasSubs = _currentSubtitles && _currentSubtitles.length > 0;

        if (isM3U8 || hasMultipleAudio || hasSubs) {
            await new Promise(resolve => requestAnimationFrame(resolve));
            openDownloadModal();
        } else {
            executeDownload(null, true);
        }
    }

    function openDownloadModal() {
        if(!els.downloadModal) return;

        els.dlQualityList.innerHTML = '';
        els.dlAudioList.innerHTML = '';
        els.dlSubsList.innerHTML = '';

        let showQuality = false;
        let showAudio = false;
        let showSubs = false;

        // Quality options
        if (hlsInstance && hlsInstance.levels && hlsInstance.levels.length > 0) {
            showQuality = true;
            const levels = hlsInstance.levels.map((l, index) => ({...l, originalIndex: index}))
                .sort((a, b) => b.height - a.height);

            levels.forEach((level, i) => {
                const isSelected = i === 0;
                const div = document.createElement('div');
                div.className = 'dl-item';
                div.innerHTML = `
                    <input type="radio" name="dl-quality" value="${level.originalIndex}" ${isSelected ? 'checked' : ''}>
                    <span>${level.height}p</span>
                    <span class="tag-info">${(level.bitrate / 1000000).toFixed(1)} Mbps</span>
                `;
                div.onclick = (e) => {
                    if(e.target.tagName !== 'INPUT') div.querySelector('input').checked = true;
                };
                els.dlQualityList.appendChild(div);
            });
        }
        document.getElementById('dl-quality-section').style.display = showQuality ? 'block' : 'none';

        // Audio tracks
        if (hlsInstance && hlsInstance.audioTracks && hlsInstance.audioTracks.length > 0) {
            showAudio = true;
            hlsInstance.audioTracks.forEach((track, index) => {
                const div = document.createElement('div');
                div.className = 'dl-item';
                div.innerHTML = `
                    <input type="checkbox" name="dl-audio" value="${index}" checked>
                    <span>${track.name || track.lang || `Audio ${index+1}`}</span>
                    <span class="tag-info">${track.lang || 'unk'}</span>
                `;
                div.onclick = (e) => {
                    if(e.target.tagName !== 'INPUT') {
                        const cb = div.querySelector('input');
                        cb.checked = !cb.checked;
                    }
                };
                els.dlAudioList.appendChild(div);
            });
        }
        document.getElementById('dl-audio-section').style.display = showAudio ? 'block' : 'none';

        // Subtitles
        if (_currentSubtitles && _currentSubtitles.length > 0) {
            showSubs = true;
            _currentSubtitles.forEach((sub, index) => {
                const div = document.createElement('div');
                div.className = 'dl-item';
                div.innerHTML = `
                    <input type="checkbox" name="dl-subs" value="${index}" checked>
                    <span>${sub.label || sub.language || 'Unknown'}</span>
                `;
                div.onclick = (e) => {
                    if(e.target.tagName !== 'INPUT') {
                        const cb = div.querySelector('input');
                        cb.checked = !cb.checked;
                    }
                };
                els.dlSubsList.appendChild(div);
            });
        }
        document.getElementById('dl-subs-section').style.display = showSubs ? 'block' : 'none';

        els.downloadModal.style.display = 'flex';
        els.downloadModal.offsetHeight;
        els.downloadModal.classList.add('show');
    }

    function closeDownloadModal() {
        if (els.downloadModal) {
            els.downloadModal.classList.remove('show');
            setTimeout(() => {
                if(!els.downloadModal.classList.contains('show')) {
                    els.downloadModal.style.display = 'none';
                }
            }, 300);
        }
    }

    async function executeDownload(e, skipModal = false) {
        closeDownloadModal();

        const btn = els.downloadBtn;
        if (!btn) return;

        const originalBtnContent = btn.innerHTML;
        btn.disabled = true;
        btn.innerHTML = `<div class="spinner" style="width:18px; height:18px; border-width:2px;"></div>`;

        // --- CAMBIO AQUÍ: Calcular duración del video actual ---
        let totalDuration = 0;
        if (els.video && isFinite(els.video.duration) && els.video.duration > 0) {
            totalDuration = Math.floor(els.video.duration);
        }
        // -------------------------------------------------------

        let body = {
            anilist_id: parseInt(_animeId),
            episode_number: parseInt(_currentEpisode),
            stream_url: _rawVideoData.url,
            headers: _rawVideoData.headers || {},
            duration: totalDuration, // <--- ENVIAMOS LA DURACIÓN
            chapters: _skipIntervals.map(i => ({
                title: i.type === 'op' ? 'Opening' : 'Ending',
                start_time: i.startTime,
                end_time: i.endTime
            })),
            subtitles: []
        };

        if (skipModal) {
            if (_currentSubtitles) {
                body.subtitles = _currentSubtitles.map(sub => ({
                    language: sub.label || 'Unknown',
                    url: sub.src
                }));
            }
        } else {
            const selectedSubs = Array.from(els.dlSubsList.querySelectorAll('input:checked'));
            body.subtitles = selectedSubs.map(cb => {
                const i = parseInt(cb.value);
                return {
                    language: _currentSubtitles[i].label || 'Unknown',
                    url: _currentSubtitles[i].src
                };
            });

            const isQualityVisible = document.getElementById('dl-quality-section').style.display !== 'none';
            if (isQualityVisible && hlsInstance && hlsInstance.levels) {
                body.is_master = true;
                const qualityInput = document.querySelector('input[name="dl-quality"]:checked');
                const qualityIndex = qualityInput ? parseInt(qualityInput.value) : 0;
                const level = hlsInstance.levels[qualityIndex];

                if (level) {
                    body.variant = {
                        resolution: level.width ? `${level.width}x${level.height}` : '1920x1080',
                        bandwidth: level.bitrate,
                        codecs: level.attrs ? level.attrs.CODECS : '',
                        playlist_url: level.url
                    };
                }

                const audioInputs = document.querySelectorAll('input[name="dl-audio"]:checked');
                if (audioInputs.length > 0 && hlsInstance.audioTracks) {
                    body.audio = Array.from(audioInputs).map(input => {
                        const i = parseInt(input.value);
                        const track = hlsInstance.audioTracks[i];
                        return {
                            group: track.groupId || 'audio',
                            language: track.lang || 'unk',
                            name: track.name || `Audio ${i}`,
                            playlist_url: track.url
                        };
                    });
                }
            }
        }

        try {
            const token = localStorage.getItem('token');
            const res = await fetch('/api/library/download/anime', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': token ? `Bearer ${token}` : ''
                },
                body: JSON.stringify(body)
            });

            const data = await res.json();

            if (res.status === 200) {
                btn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#22c55e" stroke-width="2.5"><polyline points="20 6 9 17 4 12"></polyline></svg>`;
            } else if (res.status === 409) {
                btn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2.5"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>`;
            } else {
                console.error("Download Error:", data);
                btn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`;
            }
        } catch (err) {
            console.error("Request failed:", err);
            btn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`;
        } finally {
            setTimeout(() => {
                if (btn) {
                    btn.disabled = false;
                    btn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>`;
                }
            }, 3000);
        }
    }

    // MPV functionality
    async function openInMPV() {
        if (!_rawVideoData) {
            alert("No video loaded yet.");
            return;
        }

        const token = localStorage.getItem('token');
        if (!token) {
            alert("You need to be logged in.");
            return;
        }

        const body = {
            title: `${_animeTitle} - Episode ${_currentEpisode}`,
            video: _rawVideoData,
            subtitles: _currentSubtitles,
            chapters: _skipIntervals,
            animeId: _animeId,
            episode: _currentEpisode,
            entrySource: _entrySource
            };

        try {
            const res = await fetch('/api/watch/mpv', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify(body),
            });

            if (res.ok) {
                console.log("MPV Request Sent");
                closePlayer();
            } else {
                console.error("MPV Request Failed");
            }
        } catch (e) {
            console.error("MPV Error:", e);
        }
    }

    // Match Modal
    function openMatchModal() {
        const currentExt = els.extSelect.value;
        if (!currentExt || currentExt === 'local') return;

        if (typeof MatchModal !== 'undefined') {
            MatchModal.open({
                provider: currentExt,
                initialQuery: _animeTitle,
                onSearch: async (query, prov) => {
                    const res = await fetch(`/api/search/${prov}?q=${encodeURIComponent(query)}`);
                    const data = await res.json();
                    return data.results || [];
                },
                onSelect: (item) => {
                    _manualExtensionId = item.id;
                    loadStream();
                }
            });
        }
    }

    // RPC
    function sendRPC({ startTimestamp, endTimestamp, paused = false } = {}) {
        let stateText = `Episode ${_currentEpisode}`;
        let detailsText = _animeTitle;

        if (_roomMode) {
            stateText = `Watch Party - Ep ${_currentEpisode}`;
        }

        fetch("/api/rpc", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
                details: detailsText,
                state: stateText,
                mode: "watching",
                startTimestamp,
                endTimestamp,
                paused
            })
        }).catch(e => console.warn("RPC Error:", e));
    }

    // Progress update
    async function updateProgress() {
        const token = localStorage.getItem('token');
        if (!token) return;
        try {
            await fetch('/api/list/entry', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify({
                    entry_id: _animeId,
                    source: _entrySource,
                    entry_type: "ANIME",
                    status: 'CURRENT',
                    progress: _currentEpisode
                })
            });
        } catch (e) {
            console.error("Progress update failed", e);
        }
    }

    function setRoomHost(isHost) {
        console.log('Setting player host status:', isHost);
        _isRoomHost = isHost;

        // Re-ejecutar la configuración de controles con el nuevo permiso
        setupCustomControls();

        // Forzar actualización visual si es necesario
        if (els.playerWrapper) {
            if (isHost) els.playerWrapper.classList.add('is-host');
            else els.playerWrapper.classList.remove('is-host');
        }
    }

    return {
        init,
        playEpisode,
        getCurrentEpisode: () => _currentEpisode,
        loadVideoFromRoom,
        getVideoElement: () => els.video,
        setRoomHost,
        setWebSocket
    };
})();

window.AnimePlayer = AnimePlayer;