// Custom HLS Video Player Controller
import { Store } from './store.js';

export class VideoPlayer {
  constructor(containerId) {
    this.container = document.getElementById(containerId);
    this.video = this.container.querySelector('video');
    this.controlsOverlay = this.container.querySelector('.player-controls-overlay');
    
    // Controls
    this.btnPlay = this.container.querySelector('.btn-center-play');
    this.btnSeekBack = this.container.querySelector('.btn-center-seek-back');
    this.btnSeekForward = this.container.querySelector('.btn-center-seek-forward');
    this.timeline = this.container.querySelector('.timeline-slider');
    this.timeCurrent = this.container.querySelector('.time-current');
    this.timeTotal = this.container.querySelector('.time-total');
    
    this.btnVolume = this.container.querySelector('.btn-volume');
    this.btnCast = this.container.querySelector('.btn-cast');
    this.btnSettings = this.container.querySelector('.btn-settings');
    this.btnPip = this.container.querySelector('.btn-pip');
    this.btnFullscreen = this.container.querySelector('.btn-fullscreen');
    this.btnLock = this.container.querySelector('.btn-lock');
    this.btnClose = this.container.querySelector('.btn-close-player');
    this.serversRow = this.container.querySelector('.player-servers-row');
    this.errorFallback = this.container.querySelector('.stream-error-fallback');
    this.btnDemoMode = this.container.querySelector('.btn-demo-mode');
    
    // Rotate and seek indicator overlays
    this.btnRotate = this.container.querySelector('.btn-rotate');
    this.seekIndicatorLeft = this.container.querySelector('.seek-indicator-overlay.left');
    this.seekIndicatorRight = this.container.querySelector('.seek-indicator-overlay.right');
    this.settingsPanel = this.container.querySelector('#player-settings-panel');
    
    // State
    this.hlsInstance = null;
    this.isLocked = false;
    this.currentStreamUrl = '';
    this.currentServersList = [];
    this.activeServerIndex = 0;
    this.controlsTimeout = null;

    this.initEvents();
  }

  initEvents() {
    // Play/Pause Events
    this.btnPlay.addEventListener('click', () => this.togglePlay());
    
    let lastTap = 0;
    let singleTapTimeout = null;
    this.video.addEventListener('click', (e) => {
      if (this.isLocked) return;
      
      const currentTime = new Date().getTime();
      const tapLength = currentTime - lastTap;
      if (tapLength < 300 && tapLength > 0) {
        clearTimeout(singleTapTimeout);
        const rect = this.video.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const width = rect.width;
        const seekInterval = Number(Store.getSetting('seekInterval')) || 10;

        if (x < width * 0.4) {
          this.seek(-seekInterval);
          this.showSeekIndicator('left', seekInterval);
        } else if (x > width * 0.6) {
          this.seek(seekInterval);
          this.showSeekIndicator('right', seekInterval);
        }
        e.preventDefault();
        e.stopPropagation();
      } else {
        singleTapTimeout = setTimeout(() => {
          this.togglePlay();
        }, 250);
      }
      lastTap = currentTime;
    });

    this.video.addEventListener('play', () => this.updatePlayButtonUI(true));
    this.video.addEventListener('pause', () => this.updatePlayButtonUI(false));

    // Seek Events
    this.btnSeekBack.addEventListener('click', () => {
      const seekInterval = Number(Store.getSetting('seekInterval')) || 10;
      this.seek(-seekInterval);
    });
    this.btnSeekForward.addEventListener('click', () => {
      const seekInterval = Number(Store.getSetting('seekInterval')) || 10;
      this.seek(seekInterval);
    });
    
    // Timeline Updates
    this.video.addEventListener('timeupdate', () => this.updateTimeline());
    this.timeline.addEventListener('input', () => this.onTimelineInput());

    // Volume Events
    this.btnVolume.addEventListener('click', () => this.toggleMute());
    
    // PiP, Fullscreen and Rotate
    this.btnPip.addEventListener('click', () => this.togglePip());
    this.btnFullscreen.addEventListener('click', () => this.toggleFullscreen());
    if (this.btnRotate) {
      this.btnRotate.addEventListener('click', (e) => {
        e.stopPropagation();
        this.toggleRotation();
      });
    }
    
    // Close Player
    if (this.btnClose) {
      this.btnClose.addEventListener('click', (e) => {
        e.stopPropagation();
        this.closePlayer();
      });
    }
    
    // Padlock Control Lock
    this.btnLock.addEventListener('click', (e) => {
      e.stopPropagation();
      this.toggleLock();
    });

    // Cast and Settings placeholders
    this.btnCast.addEventListener('click', () => {
      alert('Chromecast integration requires a secure HTTP context (HTTPS) and active receiver.');
    });
    this.btnSettings.addEventListener('click', (e) => {
      e.stopPropagation();
      this.toggleSettingsPanel();
    });

    // Close settings dropdown on click outside
    document.addEventListener('click', (e) => {
      if (this.settingsPanel && !this.settingsPanel.classList.contains('hidden')) {
        if (!e.target.closest('#player-settings-panel') && !e.target.closest('.btn-settings')) {
          this.settingsPanel.classList.add('hidden');
        }
      }
    });

    // Bind player settings inner screens
    if (this.settingsPanel) {
      const itemQuality = this.settingsPanel.querySelector('#item-set-quality');
      const itemSpeed = this.settingsPanel.querySelector('#item-set-speed');
      const itemSeek = this.settingsPanel.querySelector('#item-set-seek');

      if (itemQuality) {
        itemQuality.addEventListener('click', (e) => {
          e.stopPropagation();
          this.showSettingsScreen('quality');
        });
      }
      if (itemSpeed) {
        itemSpeed.addEventListener('click', (e) => {
          e.stopPropagation();
          this.showSettingsScreen('speed');
        });
      }
      if (itemSeek) {
        itemSeek.addEventListener('click', (e) => {
          e.stopPropagation();
          this.showSettingsScreen('seek');
        });
      }

      // Subscreen back buttons
      const backBtns = this.settingsPanel.querySelectorAll('.btn-settings-back');
      backBtns.forEach(btn => {
        btn.addEventListener('click', (e) => {
          e.stopPropagation();
          this.showSettingsScreen('main');
        });
      });

      // Playback Speed options
      const speedRows = this.settingsPanel.querySelectorAll('#settings-screen-speed .settings-option-row');
      speedRows.forEach(row => {
        row.addEventListener('click', (e) => {
          e.stopPropagation();
          const speed = parseFloat(row.getAttribute('data-speed'));
          this.video.playbackRate = speed;
          speedRows.forEach(r => r.classList.remove('active'));
          row.classList.add('active');
          this.updateSettingsLabels();
          this.showSettingsScreen('main');
        });
      });

      // Seek interval options
      const seekRows = this.settingsPanel.querySelectorAll('#settings-screen-seek .settings-option-row');
      seekRows.forEach(row => {
        row.addEventListener('click', (e) => {
          e.stopPropagation();
          const seekVal = parseInt(row.getAttribute('data-seek'), 10);
          Store.updateSetting('seekInterval', seekVal);
          
          // Sync with the public settings panel
          const selectSeekInterval = document.getElementById('select-seek-interval');
          if (selectSeekInterval) {
            selectSeekInterval.value = seekVal;
            const inputSeekIntervalCustom = document.getElementById('input-seek-interval-custom');
            if (inputSeekIntervalCustom) inputSeekIntervalCustom.classList.add('hidden');
          }
          
          seekRows.forEach(r => r.classList.remove('active'));
          row.classList.add('active');
          this.updateSettingsLabels();
          this.showSettingsScreen('main');
        });
      });
    }

    // Auto Hide Controls
    this.video.addEventListener('mousemove', () => this.triggerControlsVisibility());
    this.controlsOverlay.addEventListener('mousemove', () => this.triggerControlsVisibility());

    // Demo Mode Trigger
    this.btnDemoMode.addEventListener('click', () => {
      this.loadStream('https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8');
    });
  }

  loadChannel(channel) {
    this.container.querySelector('.player-title').textContent = channel.name;
    this.currentServersList = channel.servers || [{ name: 'Primary Server', url: channel.stream_url }];
    this.activeServerIndex = 0;

    // Render Server Select Chips
    this.renderServerChips();
    
    // Load active stream
    this.loadStream(this.currentServersList[0].url);
  }

  loadStream(url) {
    // Reveal the player container
    this.container.classList.remove('hidden');
    this.currentStreamUrl = url;
    this.hideErrorFallback();

    // Reset Hls Instance
    if (this.hlsInstance) {
      this.hlsInstance.destroy();
      this.hlsInstance = null;
    }

    const forceLowQuality = Store.getSetting('forceLowQuality');
    
    // Check Hls play capability
    if (url.endsWith('.m3u8') || url.includes('.m3u8')) {
      if (window.Hls && window.Hls.isSupported()) {
        this.hlsInstance = new window.Hls({
          capLevelToPlayerSize: forceLowQuality,
          maxMaxBufferLength: 30
        });
        
        this.hlsInstance.loadSource(url);
        this.hlsInstance.attachMedia(this.video);
        
        this.hlsInstance.on(window.Hls.Events.MANIFEST_PARSED, () => {
          this.play();
        });
        
        this.hlsInstance.on(window.Hls.Events.ERROR, (event, data) => {
          if (data.fatal) {
            console.error('Fatal HLS playback error:', data.type);
            this.showErrorFallback('CORS Restriction or Stream Offline', 'Browser policies block this IPTV URL because it does not allow Cross-Origin (CORS) access, or the stream is currently offline.');
          }
        });
      } else if (this.video.canPlayType('application/vnd.apple.mpegurl')) {
        // Native HLS (Safari)
        this.video.src = url;
        this.video.addEventListener('canplay', () => this.play());
      } else {
        this.showErrorFallback('Unsupported Browser', 'Your browser does not support HLS video streams natively or via Hls.js.');
      }
    } else {
      // Normal video stream (MP4/MKV etc.)
      this.video.src = url;
      this.video.load();
      this.video.addEventListener('canplay', () => this.play());
      
      this.video.onerror = () => {
        this.showErrorFallback('Playback Error', 'The stream type is not supported directly by your browser, or it returned a 404/CORS network error.');
      };
    }
  }

  play() {
    this.video.play().catch(err => {
      console.warn('Playback autoplay block:', err.message);
    });
  }

  pause() {
    this.video.pause();
  }

  togglePlay() {
    if (this.video.paused) {
      this.play();
    } else {
      this.pause();
    }
  }

  updatePlayButtonUI(isPlaying) {
    const icon = this.btnPlay.querySelector('svg');
    if (isPlaying) {
      icon.innerHTML = '<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>'; // Pause SVG Path
    } else {
      icon.innerHTML = '<path d="M8 5v14l11-7z"/>'; // Play SVG Path
    }
  }

  seek(seconds) {
    if (this.isLocked) return;
    this.video.currentTime += seconds;
  }

  updateTimeline() {
    if (isNaN(this.video.duration)) return;
    
    const value = (this.video.currentTime / this.video.duration) * 100;
    this.timeline.value = value;
    
    this.timeCurrent.textContent = this.formatTime(this.video.currentTime);
    this.timeTotal.textContent = this.formatTime(this.video.duration);
  }

  onTimelineInput() {
    if (this.isLocked || isNaN(this.video.duration)) return;
    
    const time = (this.timeline.value / 100) * this.video.duration;
    this.video.currentTime = time;
  }

  toggleMute() {
    if (this.isLocked) return;
    this.video.muted = !this.video.muted;
    const icon = this.btnVolume; // btnVolume is already the svg element
    if (this.video.muted) {
      icon.innerHTML = '<path d="M11 5 6 9H2v6h4l5 4V5z"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/>'; // Muted (Lucide volume-x)
      this.btnVolume.style.color = '#ef4444';
    } else {
      icon.innerHTML = '<path d="M11 5 6 9H2v6h4l5 4V5z"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/>'; // High Volume
      this.btnVolume.style.color = '#fff';
    }
  }

  closePlayer() {
    this.pause();
    this.container.classList.add('hidden');
    this.video.src = '';
    if (this.hlsInstance) {
      this.hlsInstance.destroy();
      this.hlsInstance = null;
    }
  }

  toggleLock() {
    this.isLocked = !this.isLocked;
    const container = this.container.querySelector('.video-container');
    const icon = this.btnLock.querySelector('svg');

    if (this.isLocked) {
      container.classList.add('locked');
      icon.innerHTML = '<path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/>'; // Locked padlock
      this.btnLock.style.color = 'var(--accent-pink)';
    } else {
      container.classList.remove('locked');
      icon.innerHTML = '<path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6-5c1.66 0 3 1.34 3 3v2H9V6c0-1.66 1.34-3 3-3z"/>'; // Unlocked padlock
      this.btnLock.style.color = '#fff';
    }
  }

  togglePip() {
    if (this.isLocked) return;
    
    if (document.pictureInPictureEnabled && this.video.requestPictureInPicture) {
      if (document.pictureInPictureElement) {
        document.exitPictureInPicture();
      } else {
        this.video.requestPictureInPicture();
      }
    } else {
      // Toggle Floating CSS Mode Fallback
      this.container.classList.toggle('floating');
    }
  }

  toggleFullscreen() {
    if (this.isLocked) return;

    const vContainer = this.container.querySelector('.video-container');
    if (!document.fullscreenElement) {
      vContainer.requestFullscreen().then(() => {
        if (screen.orientation && screen.orientation.lock) {
          screen.orientation.lock('landscape').catch(() => {});
        }
      }).catch(err => {
        alert('Fullscreen request blocked: ' + err.message);
      });
    } else {
      document.exitFullscreen();
      if (screen.orientation && screen.orientation.unlock) {
        screen.orientation.unlock();
      }
    }
  }

  toggleRotation() {
    if (this.isLocked) return;
    const vContainer = this.container.querySelector('.video-container');
    
    if (screen.orientation && screen.orientation.lock) {
      if (screen.orientation.type.startsWith('portrait')) {
        screen.orientation.lock('landscape').catch(() => {
          vContainer.classList.toggle('rotated');
        });
      } else {
        screen.orientation.unlock();
        vContainer.classList.remove('rotated');
      }
    } else {
      vContainer.classList.toggle('rotated');
    }
  }

  showSeekIndicator(direction, seconds) {
    const overlay = direction === 'left' ? this.seekIndicatorLeft : this.seekIndicatorRight;
    if (!overlay) return;

    const textEl = overlay.querySelector('.seek-text');
    if (textEl) textEl.textContent = `${direction === 'left' ? '-' : '+'}${seconds}s`;
    
    overlay.classList.remove('hidden');
    overlay.classList.add('active');

    clearTimeout(overlay.timeout);
    overlay.timeout = setTimeout(() => {
      overlay.classList.remove('active');
      overlay.classList.add('hidden');
    }, 800);
  }

  triggerControlsVisibility() {
    if (this.isLocked) return;

    const vContainer = this.container.querySelector('.video-container');
    vContainer.classList.add('show-controls');

    clearTimeout(this.controlsTimeout);
    this.controlsTimeout = setTimeout(() => {
      vContainer.classList.remove('show-controls');
    }, 3000);
  }

  renderServerChips() {
    this.serversRow.innerHTML = '';
    this.currentServersList.forEach((server, index) => {
      const chip = document.createElement('div');
      chip.className = `server-chip ${index === this.activeServerIndex ? 'active' : ''}`;
      chip.innerHTML = `${index === this.activeServerIndex ? '✓ ' : ''}${server.name}`;
      chip.addEventListener('click', () => {
        if (index === this.activeServerIndex) return;
        this.activeServerIndex = index;
        this.renderServerChips();
        this.loadStream(server.url);
      });
      this.serversRow.appendChild(chip);
    });
  }

  showErrorFallback(title, message) {
    this.errorFallback.querySelector('.stream-error-title').textContent = title;
    this.errorFallback.querySelector('.stream-error-msg').textContent = message;
    this.errorFallback.classList.remove('hidden');
  }

  hideErrorFallback() {
    this.errorFallback.classList.add('hidden');
  }

  toggleSettingsPanel() {
    if (this.isLocked) return;
    this.settingsPanel.classList.toggle('hidden');
    if (!this.settingsPanel.classList.contains('hidden')) {
      this.showSettingsScreen('main');
      this.populateQualityOptions();
      this.updateSettingsLabels();
    }
  }

  showSettingsScreen(screenName) {
    const screens = this.settingsPanel.querySelectorAll('.settings-screen');
    screens.forEach(screen => {
      if (screen.id === `settings-screen-${screenName}`) {
        screen.classList.remove('hidden');
        screen.classList.add('active');
      } else {
        screen.classList.remove('active');
        screen.classList.add('hidden');
      }
    });
  }

  updateSettingsLabels() {
    const lblQuality = this.settingsPanel.querySelector('#lbl-set-quality');
    const lblSpeed = this.settingsPanel.querySelector('#lbl-set-speed');
    const lblSeek = this.settingsPanel.querySelector('#lbl-set-seek');

    if (lblSpeed) {
      const speed = this.video.playbackRate;
      lblSpeed.textContent = speed === 1.0 ? 'Normal' : `${speed}x`;
    }

    if (lblSeek) {
      const seekInterval = Store.getSetting('seekInterval') || 10;
      lblSeek.textContent = `${seekInterval}s`;
    }

    if (lblQuality) {
      if (this.hlsInstance && this.hlsInstance.levels.length > 0) {
        const idx = this.hlsInstance.currentLevel;
        if (idx === -1) {
          lblQuality.textContent = 'Auto';
        } else {
          const height = this.hlsInstance.levels[idx].height;
          lblQuality.textContent = `${height}p`;
        }
      } else {
        lblQuality.textContent = 'Auto';
      }
    }
  }

  populateQualityOptions() {
    const listQuality = this.settingsPanel.querySelector('#list-set-quality');
    if (!listQuality) return;

    listQuality.innerHTML = '';

    if (!this.hlsInstance || this.hlsInstance.levels.length === 0) {
      listQuality.innerHTML = '<div style="padding:12px; text-align:center; font-size:0.75rem; color:var(--text-muted);">Auto Quality Only</div>';
      return;
    }

    // Auto option row
    const autoRow = document.createElement('div');
    autoRow.className = `settings-option-row ${this.hlsInstance.loadLevel === -1 ? 'active' : ''}`;
    autoRow.textContent = 'Auto';
    autoRow.addEventListener('click', (e) => {
      e.stopPropagation();
      this.hlsInstance.loadLevel = -1;
      this.updateSettingsLabels();
      this.showSettingsScreen('main');
    });
    listQuality.appendChild(autoRow);

    // Dynamic resolution quality rows
    const levels = this.hlsInstance.levels;
    levels.forEach((level, index) => {
      const row = document.createElement('div');
      row.className = `settings-option-row ${this.hlsInstance.loadLevel === index ? 'active' : ''}`;
      row.textContent = `${level.height}p`;
      row.addEventListener('click', (e) => {
        e.stopPropagation();
        this.hlsInstance.loadLevel = index;
        this.updateSettingsLabels();
        this.showSettingsScreen('main');
      });
      listQuality.appendChild(row);
    });
  }

  formatTime(seconds) {
    if (isNaN(seconds) || seconds === Infinity) return '00:00';
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
  }
}
