/**
 * EasyStream Video Player
 * Advanced HTML5 video player with HLS support
 */
class EasyStreamPlayer {
    constructor(containerId, config) {
        this.container = document.getElementById(containerId);
        this.config = config;
        this.video = null;
        this.hls = null;
        this.currentQuality = 'auto';
        this.isFullscreen = false;
        this.controlsTimeout = null;
        this.progressUpdateInterval = null;
        
        this.init();
    }
    
    init() {
        this.video = this.container.querySelector('.video-element');
        this.setupEventListeners();
        this.loadVideo();
        this.setupProgressTracking();
        
        // Load HLS.js if needed
        if (this.config.hlsSupported && !window.Hls) {
            this.loadHLSLibrary();
        }
    }
    
    setupEventListeners() {
        const controls = this.container.querySelector('.video-controls');
        const bigPlayBtn = this.container.querySelector('.big-play-button');
        
        // Video events
        this.video.addEventListener('loadstart', () => this.showLoading());
        this.video.addEventListener('canplay', () => this.hideLoading());
        this.video.addEventListener('play', () => this.onPlay());
        this.video.addEventListener('pause', () => this.onPause());
        this.video.addEventListener('timeupdate', () => this.updateProgress());
        this.video.addEventListener('durationchange', () => this.updateDuration());
        this.video.addEventListener('progress', () => this.updateBuffer());
        this.video.addEventListener('error', (e) => this.onError(e));
        this.video.addEventListener('ended', () => this.onEnded());
        
        // Control events
        this.setupControlEvents();
        
        // Big play button
        bigPlayBtn.addEventListener('click', () => this.togglePlay());
        
        // Container hover for controls
        this.container.addEventListener('mouseenter', () => this.showControls());
        this.container.addEventListener('mouseleave', () => this.hideControlsDelayed());
        this.container.addEventListener('mousemove', () => this.showControls());
        
        // Touch events for mobile
        this.setupTouchEvents();
        
        // Keyboard shortcuts
        this.setupKeyboardShortcuts();
        
        // Fullscreen events
        document.addEventListener('fullscreenchange', () => this.onFullscreenChange());
        document.addEventListener('webkitfullscreenchange', () => this.onFullscreenChange());
        document.addEventListener('mozfullscreenchange', () => this.onFullscreenChange());
        document.addEventListener('MSFullscreenChange', () => this.onFullscreenChange());
    }
    
    setupControlEvents() {
        const controls = this.container.querySelector('.video-controls');
        
        // Play/Pause button
        const playPauseBtn = controls.querySelector('.play-pause-btn');
        playPauseBtn.addEventListener('click', () => this.togglePlay());
        
        // Progress bar
        const progressBar = controls.querySelector('.progress-bar');
        progressBar.addEventListener('click', (e) => this.seekToPosition(e));
        progressBar.addEventListener('mousedown', (e) => this.startSeeking(e));
        
        // Volume controls
        const volumeBtn = controls.querySelector('.volume-btn');
        const volumeBar = controls.querySelector('.volume-bar');
        volumeBtn.addEventListener('click', () => this.toggleMute());
        volumeBar.addEventListener('click', (e) => this.setVolume(e));
        
        // Quality selector
        const qualityOptions = controls.querySelectorAll('.quality-option');
        qualityOptions.forEach(option => {
            option.addEventListener('click', () => this.changeQuality(option.dataset.quality));
        });
        
        // Speed selector
        const speedOptions = controls.querySelectorAll('.speed-option');
        speedOptions.forEach(option => {
            option.addEventListener('click', () => this.changeSpeed(parseFloat(option.dataset.speed)));
        });
        
        // Fullscreen button
        const fullscreenBtn = controls.querySelector('.fullscreen-btn');
        fullscreenBtn.addEventListener('click', () => this.toggleFullscreen());
        
        // Picture-in-Picture button
        const pipBtn = controls.querySelector('.pip-btn');
        if (pipBtn && 'pictureInPictureEnabled' in document) {
            pipBtn.style.display = 'block';
            pipBtn.addEventListener('click', () => this.togglePictureInPicture());
        }
    }
    
    setupTouchEvents() {
        let touchStartX = 0;
        let touchStartY = 0;
        let touchStartTime = 0;
        
        this.container.addEventListener('touchstart', (e) => {
            touchStartX = e.touches[0].clientX;
            touchStartY = e.touches[0].clientY;
            touchStartTime = this.video.currentTime;
        });
        
        this.container.addEventListener('touchmove', (e) => {
            e.preventDefault();
            const touchX = e.touches[0].clientX;
            const touchY = e.touches[0].clientY;
            const deltaX = touchX - touchStartX;
            const deltaY = touchY - touchStartY;
            
            // Horizontal swipe for seeking
            if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 50) {
                const seekAmount = (deltaX / this.container.offsetWidth) * this.video.duration;
                const newTime = Math.max(0, Math.min(this.video.duration, touchStartTime + seekAmount));
                this.video.currentTime = newTime;
            }
            
            // Vertical swipe for volume (left side) or brightness (right side)
            if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > 50) {
                if (touchStartX < this.container.offsetWidth / 2) {
                    // Left side - volume
                    const volumeChange = -deltaY / this.container.offsetHeight;
                    const newVolume = Math.max(0, Math.min(1, this.video.volume + volumeChange));
                    this.video.volume = newVolume;
                    this.updateVolumeDisplay();
                }
            }
        });
        
        this.container.addEventListener('touchend', () => {
            this.showControls();
            this.hideControlsDelayed();
        });
    }
    
    setupKeyboardShortcuts() {
        document.addEventListener('keydown', (e) => {
            if (!this.isPlayerFocused()) return;
            
            switch (e.code) {
                case 'Space':
                    e.preventDefault();
                    this.togglePlay();
                    break;
                case 'ArrowLeft':
                    e.preventDefault();
                    this.seek(-10);
                    break;
                case 'ArrowRight':
                    e.preventDefault();
                    this.seek(10);
                    break;
                case 'ArrowUp':
                    e.preventDefault();
                    this.changeVolume(0.1);
                    break;
                case 'ArrowDown':
                    e.preventDefault();
                    this.changeVolume(-0.1);
                    break;
                case 'KeyM':
                    e.preventDefault();
                    this.toggleMute();
                    break;
                case 'KeyF':
                    e.preventDefault();
                    this.toggleFullscreen();
                    break;
                case 'Escape':
                    if (this.isFullscreen) {
                        this.exitFullscreen();
                    }
                    break;
            }
        });
    }
    
    loadVideo() {
        this.showLoading();
        
        // Get stream information
        fetch(`/stream.php?v=${this.config.videoKey}`)
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    this.setupVideoSources(data);
                    
                    // Set start time if specified
                    if (this.config.startTime > 0) {
                        this.video.currentTime = this.config.startTime;
                    }
                    
                    // Autoplay if enabled
                    if (this.config.autoplay) {
                        this.play();
                    }
                } else {
                    this.showError(data.error || 'Failed to load video');
                }
            })
            .catch(error => {
                console.error('Error loading video:', error);
                this.showError('Failed to load video');
            });
    }
    
    setupVideoSources(streamData) {
        // Clear existing sources
        this.video.innerHTML = '';
        
        if (streamData.streams.hls && this.supportsHLS()) {
            // Use HLS for adaptive streaming
            this.setupHLS(streamData.streams.hls.url);
        } else if (streamData.streams.progressive) {
            // Use progressive download
            this.setupProgressive(streamData.streams.progressive);
        } else {
            this.showError('No compatible video format available');
            return;
        }
        
        // Update quality options
        this.updateQualityOptions(streamData.streams);
    }
    
    setupHLS(hlsUrl) {
        if (window.Hls && Hls.isSupported()) {
            this.hls = new Hls({
                enableWorker: true,
                lowLatencyMode: false,
                backBufferLength: 90
            });
            
            this.hls.loadSource(hlsUrl);
            this.hls.attachMedia(this.video);
            
            this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
                console.log('HLS manifest loaded');
                this.hideLoading();
            });
            
            this.hls.on(Hls.Events.ERROR, (event, data) => {
                console.error('HLS error:', data);
                if (data.fatal) {
                    this.showError('Video streaming error');
                }
            });
        } else if (this.video.canPlayType('application/vnd.apple.mpegurl')) {
            // Native HLS support (Safari)
            this.video.src = hlsUrl;
        } else {
            this.showError('HLS not supported');
        }
    }
    
    setupProgressive(progressiveStreams) {
        // Sort qualities by resolution (highest first)
        const sortedQualities = Object.entries(progressiveStreams)
            .sort((a, b) => this.getResolutionValue(b[0]) - this.getResolutionValue(a[0]));
        
        // Add source elements
        sortedQualities.forEach(([quality, stream]) => {
            const source = document.createElement('source');
            source.src = stream.url;
            source.type = stream.type;
            source.setAttribute('data-quality', quality);
            this.video.appendChild(source);
        });
        
        // Set default quality
        if (sortedQualities.length > 0) {
            this.video.src = sortedQualities[0][1].url;
            this.currentQuality = sortedQualities[0][0];
        }
    }
    
    loadHLSLibrary() {
        const script = document.createElement('script');
        script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';
        script.onload = () => {
            console.log('HLS.js loaded');
            this.loadVideo();
        };
        document.head.appendChild(script);
    }
    
    supportsHLS() {
        return window.Hls && Hls.isSupported() || 
               this.video.canPlayType('application/vnd.apple.mpegurl');
    }
    
    togglePlay() {
        if (this.video.paused) {
            this.play();
        } else {
            this.pause();
        }
    }
    
    play() {
        const playPromise = this.video.play();
        
        if (playPromise !== undefined) {
            playPromise
                .then(() => {
                    console.log('Video started playing');
                })
                .catch(error => {
                    console.error('Error playing video:', error);
                    this.showError('Unable to play video');
                });
        }
    }
    
    pause() {
        this.video.pause();
    }
    
    seek(seconds) {
        const newTime = Math.max(0, Math.min(this.video.duration, this.video.currentTime + seconds));
        this.video.currentTime = newTime;
    }
    
    seekToPosition(e) {
        const progressBar = e.currentTarget;
        const rect = progressBar.getBoundingClientRect();
        const position = (e.clientX - rect.left) / rect.width;
        const newTime = position * this.video.duration;
        this.video.currentTime = newTime;
    }
    
    changeVolume(delta) {
        const newVolume = Math.max(0, Math.min(1, this.video.volume + delta));
        this.video.volume = newVolume;
        this.updateVolumeDisplay();
    }
    
    toggleMute() {
        this.video.muted = !this.video.muted;
        this.updateVolumeDisplay();
    }
    
    setVolume(e) {
        const volumeBar = e.currentTarget;
        const rect = volumeBar.getBoundingClientRect();
        const position = 1 - ((e.clientY - rect.top) / rect.height);
        const newVolume = Math.max(0, Math.min(1, position));
        this.video.volume = newVolume;
        this.video.muted = false;
        this.updateVolumeDisplay();
    }
    
    changeQuality(quality) {
        if (quality === this.currentQuality) return;
        
        const currentTime = this.video.currentTime;
        const wasPlaying = !this.video.paused;
        
        if (quality === 'auto' && this.hls) {
            this.hls.currentLevel = -1; // Auto quality
        } else if (this.hls) {
            // Find HLS level for quality
            const levels = this.hls.levels;
            const targetLevel = levels.findIndex(level => 
                level.height === this.getResolutionValue(quality)
            );
            if (targetLevel !== -1) {
                this.hls.currentLevel = targetLevel;
            }
        } else {
            // Progressive quality change
            const sources = this.video.querySelectorAll('source');
            const targetSource = Array.from(sources).find(source => 
                source.getAttribute('data-quality') === quality
            );
            if (targetSource) {
                this.video.src = targetSource.src;
                this.video.currentTime = currentTime;
                if (wasPlaying) {
                    this.video.play();
                }
            }
        }
        
        this.currentQuality = quality;
        this.updateQualityDisplay();
    }
    
    changeSpeed(speed) {
        this.video.playbackRate = speed;
        this.updateSpeedDisplay();
    }
    
    toggleFullscreen() {
        if (this.isFullscreen) {
            this.exitFullscreen();
        } else {
            this.enterFullscreen();
        }
    }
    
    enterFullscreen() {
        const element = this.container;
        
        if (element.requestFullscreen) {
            element.requestFullscreen();
        } else if (element.webkitRequestFullscreen) {
            element.webkitRequestFullscreen();
        } else if (element.mozRequestFullScreen) {
            element.mozRequestFullScreen();
        } else if (element.msRequestFullscreen) {
            element.msRequestFullscreen();
        }
    }
    
    exitFullscreen() {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        } else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
        }
    }
    
    togglePictureInPicture() {
        if (document.pictureInPictureElement) {
            document.exitPictureInPicture();
        } else {
            this.video.requestPictureInPicture();
        }
    }
    
    // Event handlers
    onPlay() {
        this.updatePlayPauseButton();
        this.hideBigPlayButton();
        this.startProgressTracking();
    }
    
    onPause() {
        this.updatePlayPauseButton();
        this.showBigPlayButton();
        this.stopProgressTracking();
    }
    
    onEnded() {
        this.showBigPlayButton();
        this.stopProgressTracking();
        this.updateProgress();
    }
    
    onError(e) {
        console.error('Video error:', e);
        this.showError('Video playback error');
    }
    
    onFullscreenChange() {
        this.isFullscreen = !!(document.fullscreenElement || 
                              document.webkitFullscreenElement || 
                              document.mozFullScreenElement || 
                              document.msFullscreenElement);
        this.updateFullscreenButton();
    }
    
    // UI Updates
    updatePlayPauseButton() {
        const playIcon = this.container.querySelector('.play-pause-btn .icon-play');
        const pauseIcon = this.container.querySelector('.play-pause-btn .icon-pause');
        
        if (this.video.paused) {
            playIcon.style.display = 'inline';
            pauseIcon.style.display = 'none';
        } else {
            playIcon.style.display = 'none';
            pauseIcon.style.display = 'inline';
        }
    }
    
    updateProgress() {
        if (!this.video.duration) return;
        
        const progress = (this.video.currentTime / this.video.duration) * 100;
        const progressPlayed = this.container.querySelector('.progress-played');
        const progressHandle = this.container.querySelector('.progress-handle');
        
        progressPlayed.style.width = progress + '%';
        progressHandle.style.left = progress + '%';
        
        this.updateTimeDisplay();
    }
    
    updateBuffer() {
        if (!this.video.duration || !this.video.buffered.length) return;
        
        const buffered = this.video.buffered.end(this.video.buffered.length - 1);
        const progress = (buffered / this.video.duration) * 100;
        const progressBuffer = this.container.querySelector('.progress-buffer');
        
        progressBuffer.style.width = progress + '%';
    }
    
    updateDuration() {
        this.updateTimeDisplay();
    }
    
    updateTimeDisplay() {
        const currentTimeEl = this.container.querySelector('.current-time');
        const durationEl = this.container.querySelector('.duration');
        
        currentTimeEl.textContent = this.formatTime(this.video.currentTime);
        durationEl.textContent = this.formatTime(this.video.duration || 0);
    }
    
    updateVolumeDisplay() {
        const volumeFill = this.container.querySelector('.volume-fill');
        const volumeIcon = this.container.querySelector('.volume-btn i');
        
        const volume = this.video.muted ? 0 : this.video.volume;
        volumeFill.style.height = (volume * 100) + '%';
        
        // Update volume icon
        if (this.video.muted || volume === 0) {
            volumeIcon.className = 'icon-volume-off';
        } else {
            volumeIcon.className = 'icon-volume-up';
        }
    }
    
    updateQualityDisplay() {
        const qualityLabel = this.container.querySelector('.quality-label');
        const qualityOptions = this.container.querySelectorAll('.quality-option');
        
        qualityLabel.textContent = this.currentQuality === 'auto' ? 'Auto' : this.currentQuality;
        
        qualityOptions.forEach(option => {
            option.classList.toggle('active', option.dataset.quality === this.currentQuality);
        });
    }
    
    updateSpeedDisplay() {
        const speedLabel = this.container.querySelector('.speed-label');
        const speedOptions = this.container.querySelectorAll('.speed-option');
        
        speedLabel.textContent = this.video.playbackRate + 'x';
        
        speedOptions.forEach(option => {
            option.classList.toggle('active', 
                parseFloat(option.dataset.speed) === this.video.playbackRate);
        });
    }
    
    updateFullscreenButton() {
        const fullscreenIcon = this.container.querySelector('.fullscreen-btn .icon-fullscreen');
        const exitFullscreenIcon = this.container.querySelector('.fullscreen-btn .icon-fullscreen-exit');
        
        if (this.isFullscreen) {
            fullscreenIcon.style.display = 'none';
            exitFullscreenIcon.style.display = 'inline';
        } else {
            fullscreenIcon.style.display = 'inline';
            exitFullscreenIcon.style.display = 'none';
        }
    }
    
    // Controls visibility
    showControls() {
        const controls = this.container.querySelector('.video-controls');
        controls.classList.add('show');
        
        if (this.controlsTimeout) {
            clearTimeout(this.controlsTimeout);
        }
    }
    
    hideControlsDelayed() {
        if (this.controlsTimeout) {
            clearTimeout(this.controlsTimeout);
        }
        
        this.controlsTimeout = setTimeout(() => {
            const controls = this.container.querySelector('.video-controls');
            controls.classList.remove('show');
        }, 3000);
    }
    
    showBigPlayButton() {
        const bigPlayBtn = this.container.querySelector('.big-play-button');
        bigPlayBtn.style.display = 'flex';
    }
    
    hideBigPlayButton() {
        const bigPlayBtn = this.container.querySelector('.big-play-button');
        bigPlayBtn.style.display = 'none';
    }
    
    showLoading() {
        const loading = this.container.querySelector('.video-loading');
        loading.style.display = 'block';
    }
    
    hideLoading() {
        const loading = this.container.querySelector('.video-loading');
        loading.style.display = 'none';
    }
    
    showError(message) {
        const error = this.container.querySelector('.video-error');
        const errorMessage = error.querySelector('.error-message');
        
        errorMessage.textContent = message;
        error.style.display = 'flex';
        
        // Retry button
        const retryBtn = error.querySelector('.retry-btn');
        retryBtn.onclick = () => {
            error.style.display = 'none';
            this.loadVideo();
        };
    }
    
    // Progress tracking for analytics
    setupProgressTracking() {
        if (!this.config.userId) return;
        
        // Track progress every 10 seconds
        this.progressUpdateInterval = setInterval(() => {
            this.updateWatchProgress();
        }, 10000);
        
        // Track on pause/seek
        this.video.addEventListener('pause', () => this.updateWatchProgress());
        this.video.addEventListener('seeked', () => this.updateWatchProgress());
    }
    
    startProgressTracking() {
        if (this.progressUpdateInterval) return;
        this.setupProgressTracking();
    }
    
    stopProgressTracking() {
        if (this.progressUpdateInterval) {
            clearInterval(this.progressUpdateInterval);
            this.progressUpdateInterval = null;
        }
        this.updateWatchProgress();
    }
    
    updateWatchProgress() {
        if (!this.config.userId || !this.video.duration) return;
        
        const data = {
            video_key: this.config.videoKey,
            current_time: this.video.currentTime,
            duration: this.video.duration,
            csrf_token: this.config.csrfToken
        };
        
        fetch('/api/video/progress', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(data)
        }).catch(error => {
            console.error('Error updating progress:', error);
        });
    }
    
    // Utility methods
    formatTime(seconds) {
        if (!seconds || isNaN(seconds)) return '0:00';
        
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        const secs = Math.floor(seconds % 60);
        
        if (hours > 0) {
            return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
        } else {
            return `${minutes}:${secs.toString().padStart(2, '0')}`;
        }
    }
    
    getResolutionValue(quality) {
        const resolutions = {
            '1080p': 1080,
            '720p': 720,
            '480p': 480,
            '360p': 360,
            '240p': 240
        };
        return resolutions[quality] || 0;
    }
    
    isPlayerFocused() {
        return this.container.contains(document.activeElement) || 
               document.activeElement === document.body;
    }
    
    updateQualityOptions(streams) {
        const qualityMenu = this.container.querySelector('.quality-menu');
        
        // Clear existing options except auto
        const autoOption = qualityMenu.querySelector('[data-quality="auto"]');
        qualityMenu.innerHTML = '';
        qualityMenu.appendChild(autoOption);
        
        // Add available qualities
        if (streams.progressive) {
            Object.keys(streams.progressive).forEach(quality => {
                const option = document.createElement('div');
                option.className = 'quality-option';
                option.dataset.quality = quality;
                option.textContent = this.getQualityLabel(quality);
                option.addEventListener('click', () => this.changeQuality(quality));
                qualityMenu.appendChild(option);
            });
        }
    }
    
    getQualityLabel(quality) {
        const labels = {
            '1080p': '1080p HD',
            '720p': '720p HD',
            '480p': '480p',
            '360p': '360p',
            '240p': '240p'
        };
        return labels[quality] || quality;
    }
}

// Export for use in other scripts
window.EasyStreamPlayer = EasyStreamPlayer;