# wcs/player_monitor.py

import xbmc
import xbmcgui
import xbmcaddon
import threading
import time
import traceback
from urllib.parse import quote_plus

from wcs.playback.DialogMediaInfoWithGame import get_autoplay_manager
from wcs.playback.DialogMediaInfoWithGame import get_episode_info_manager

class AutoplayPlayerMonitor(xbmc.Player):
    """
    Monitor přehrávání pro autoplay funkcionalitu.
    Sleduje přehrávání epizod a zobrazuje dialogy podle potřeby.
    """
    
    _instance = None
    _initialized = False
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if self._initialized:
            return
            
        super().__init__()
        self.addon = xbmcaddon.Addon()
        self.autoplay_manager = get_autoplay_manager()
        self.episode_info_manager = get_episode_info_manager()
        
        # Informace o přehrávané epizodě
        self.is_playing_episode = False
        self.autoplay_active = False
        self.total_time = 0
        self.countdown_shown = False
        self.info_shown = False
        
        # Monitor thread
        self.monitor_thread = None
        self.is_monitoring = False
        
        # Flag pro zabránění duplicitního spuštění
        self._manual_activation = False

        # Guard proti duplicitnímu spuštění další epizody (race při timeoutu)
        self._handling_next = False
        self._next_episode_lock = threading.Lock()

        self._initialized = True
        xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Initialized (singleton) - ready to monitor playback", level=xbmc.LOGINFO)
    
    def onPlayBackStarted(self):
        """Voláno když začne přehrávání."""
        xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Playback started", level=xbmc.LOGINFO)
        
        # Kontrola zda už je aktivace v procesu manuálně
        if hasattr(self, '_manual_activation') and self._manual_activation:
            xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Manual activation in progress, skipping callback activation", level=xbmc.LOGINFO)
            self._manual_activation = False  # Reset flag
            return
        
        # Kontrola zda je to naše testovací přehrávání
        try:
            temp_autoplay_active = self.addon.getSetting('temp_autoplay_active')
            xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: temp_autoplay_active = '{temp_autoplay_active}'", level=xbmc.LOGINFO)
            
            if temp_autoplay_active == 'true':
                # Je to naše testovací přehrávání - spustíme monitoring
                xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Test playback detected", level=xbmc.LOGINFO)
                
                # Spuštění v threadu aby neblokoval UI - s delší pauzou
                threading.Thread(target=self._handle_test_playback_start, daemon=True).start()
                
                # Vymazat dočasný stav
                try:
                    self.addon.setSetting('temp_autoplay_active', 'false')
                    xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Cleared temp_autoplay_active", level=xbmc.LOGINFO)
                except Exception as e:
                    xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error clearing temp_autoplay_active: {e}", level=xbmc.LOGWARNING)
            else:
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Regular playback, ignoring (temp_autoplay_active='{temp_autoplay_active}')", level=xbmc.LOGDEBUG)
        except Exception as e:
            xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error checking temp_autoplay_active: {e}", level=xbmc.LOGERROR)
    
    def _handle_test_playback_start(self):
        """Zpracuje začátek testovacího přehrávání v separátním threadu."""
        # Kratší pauza pro rychlejší zobrazení episode info dialogu
        time.sleep(3)  # Zkráceno z 8 na 3 sekundy pro rychlejší odezvu
        
        if self.isPlaying():
            try:
                self.total_time = self.getTotalTime()
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Total time: {self.total_time}", level=xbmc.LOGINFO)
                
                # Reset stavu pro nové přehrávání
                self.info_shown = False
                self.countdown_shown = False
                
                # Vždy zobrazit episode info dialog (po delší pauze)
                self._show_episode_info()
                
                # Načíst aktuální stav autoplay z manageru
                if self.autoplay_manager.autoplay_enabled:
                    self.autoplay_active = True
                    self.is_playing_episode = True
                    
                    # Spuštění monitoring threadu pro countdown
                    self._start_monitoring()
                else:
                    xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Autoplay disabled, showing episode info only", level=xbmc.LOGINFO)
                    # Zajistíme že monitoring neběží
                    self.autoplay_active = False
                    self.is_playing_episode = False
                    
            except Exception as e:
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error in _handle_test_playback_start: {e}", level=xbmc.LOGERROR)
    
    def onPlayBackStopped(self):
        """Voláno když skončí přehrávání."""
        xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Playback stopped", level=xbmc.LOGINFO)
        self._stop_monitoring()
        
    def onPlayBackEnded(self):
        """Voláno když skončí přehrávání (konec souboru)."""
        xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Playback ended", level=xbmc.LOGINFO)
        self._stop_monitoring()
        
    def onPlayBackSeek(self, time, seekOffset):
        """Voláno při přetočení."""
        if self.autoplay_active and self.isPlaying():
            try:
                current_time = self.getTime()
                remaining_time = self.total_time - current_time
                
                # Kdy zobrazit countdown
                countdown_seconds = self.autoplay_manager.countdown_seconds
                
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Seek - current: {current_time}, remaining: {remaining_time}", level=xbmc.LOGDEBUG)
                
                # Pokud uživatel přetočil na countdown zónu a countdown ještě nebyl zobrazen
                if remaining_time <= countdown_seconds and not self.countdown_shown:
                    xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: User seeked to countdown zone (remaining: {remaining_time:.1f}s)", level=xbmc.LOGINFO)
                    # Spuštění countdown dialogu v separátním threadu s aktuálním zbývajícím časem
                    threading.Thread(target=self._show_countdown_dialog, daemon=True).start()
                    
            except Exception as e:
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error in onPlayBackSeek: {e}", level=xbmc.LOGERROR)
    
    def _start_monitoring(self):
        """Spustí monitoring thread."""
        if not self.is_monitoring:
            self.is_monitoring = True
            self.monitor_thread = threading.Thread(target=self._monitor_worker)
            self.monitor_thread.daemon = True
            self.monitor_thread.start()
            
    def _stop_monitoring(self):
        """Zastaví monitoring."""
        self.is_monitoring = False
        self.autoplay_active = False
        self.is_playing_episode = False
        
    def _monitor_worker(self):
        """Worker thread pro monitoring času přehrávání."""
        # Používáme countdown_seconds - kdy zobrazit countdown dialog
        countdown_seconds = self.autoplay_manager.countdown_seconds
        trigger_seconds = self.autoplay_manager.trigger_seconds
        
        xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Starting monitoring (show countdown at {countdown_seconds}s before end, trigger at {trigger_seconds}s)", level=xbmc.LOGINFO)
        
        while self.is_monitoring:
            try:
                # Kontrola zda stále přehráváme
                if not self.isPlaying():
                    xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Player stopped, ending monitoring", level=xbmc.LOGINFO)
                    break
                
                # Kontrola zda je stále autoplay aktivní
                if not self.autoplay_manager.autoplay_enabled:
                    xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Autoplay disabled, ending monitoring", level=xbmc.LOGINFO)
                    break
                    
                current_time = self.getTime()
                remaining_time = self.total_time - current_time
                
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: {current_time:.1f}s/{self.total_time:.1f}s (remaining: {remaining_time:.1f}s, countdown at: {countdown_seconds}s)", level=xbmc.LOGDEBUG)
                
                # Zobrazit countdown dialog X sekund před koncem
                if remaining_time <= countdown_seconds and not self.countdown_shown:
                    xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Showing countdown dialog (remaining: {remaining_time:.1f}s)", level=xbmc.LOGINFO)
                    self._show_countdown_dialog()
                    break  # Přerušíme monitoring po zobrazení dialogu
                    
                # Čekání 1 sekundu
                time.sleep(1)
                
            except Exception as e:
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error in monitor worker: {e}", level=xbmc.LOGERROR)
                break
        
        # Cleanup při ukončení monitoring
        self._stop_monitoring()
        xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Monitor worker ended", level=xbmc.LOGINFO)
        
    def _show_episode_info(self):
        """Zobrazí episode info dialog s reálnými daty nebo mock daty pro testování."""
        if not self.info_shown:
            self.info_shown = True
            
            # Kontrola zda je episode info povoleno v nastavení
            try:
                addon = xbmcaddon.Addon()
                if not addon.getSettingBool('show_episode_info'):
                    xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Episode info disabled in settings", level=xbmc.LOGDEBUG)
                    return
            except Exception as e:
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error checking episode info setting: {e}", level=xbmc.LOGWARNING)
            
            xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Attempting to show episode info dialog", level=xbmc.LOGINFO)
            
            try:
                from wcs.playback.metadata import MediaMetadata
                
                current_series = self.autoplay_manager.current_series_info
                current_episode = self.autoplay_manager.current_episode_info
                
                if current_series and current_episode:
                    # Získání metadat z knihovny
                    from wcs.library.LibraryManager import get_episode_metadata_from_library
                    raw_data = get_episode_metadata_from_library(
                        current_series['name'], 
                        current_episode['season'], 
                        current_episode['episode']
                    )
                    
                    if raw_data:
                        metadata = MediaMetadata.from_kodi_library_episode(raw_data)
                    else:
                        metadata = MediaMetadata(
                            media_type='series',
                            title=current_series['name'],
                            series_name=current_series['name'],
                            episode_title=f"S{current_episode['season']:02d}E{current_episode['episode']:02d}",
                            season_number=current_episode['season'],
                            episode_number=current_episode['episode'],
                        )
                else:
                    # Mock data pro testování
                    metadata = MediaMetadata(
                        media_type='series',
                        title="Test Seriál",
                        series_name="Test Seriál",
                        episode_title="Test Epizoda",
                        season_number=1,
                        episode_number=1,
                        rating="8.5",
                        year="2024",
                        plot="Testovací popis epizody pro ukázku funkčnosti.",
                    )
                
                self.episode_info_manager.show_episode_info(
                    metadata.series_name,
                    metadata.episode_title,
                    metadata.season_number,
                    metadata.episode_number,
                    metadata.thumb,
                    metadata.rating,
                    metadata.year,
                    metadata.plot,
                )
                
                xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Episode info dialog shown successfully", level=xbmc.LOGINFO)
            except Exception as e:
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error showing episode info: {e}", level=xbmc.LOGERROR)
                import traceback
                traceback.print_exc()
            
    def _show_countdown_dialog(self):
        """Zobrazí countdown dialog."""
        if not self.countdown_shown:
            self.countdown_shown = True
            
            try:
                # Získat aktuální zbývající čas při zobrazení dialogu
                current_remaining_time = 0
                if self.isPlaying():
                    try:
                        current_time = self.getTime()
                        current_remaining_time = self.total_time - current_time
                        xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Current remaining time when showing dialog: {current_remaining_time:.1f}s", level=xbmc.LOGINFO)
                    except Exception as e:
                        xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error getting current time: {e}", level=xbmc.LOGWARNING)
                        current_remaining_time = self.autoplay_manager.countdown_seconds  # fallback
                
                action = self.autoplay_manager.show_countdown_dialog(current_remaining_time)
                
                # Zpracování výsledku
                if action == self.autoplay_manager.ACTION_PLAY_NOW:
                    xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: User chose play now", level=xbmc.LOGINFO)
                    # Zastavit přehrávání a spustit další epizodu (manuálně)
                    self._handle_next_episode(is_manual=True)
                elif action == self.autoplay_manager.ACTION_CANCEL_AUTOPLAY:
                    xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: User cancelled autoplay", level=xbmc.LOGINFO)
                    self.autoplay_manager.set_autoplay_enabled(False)
                    self._stop_monitoring()
                elif action == self.autoplay_manager.ACTION_TIMEOUT:
                    xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Countdown timeout - auto play", level=xbmc.LOGINFO)
                    # Automatické spuštění další epizody
                    self._handle_next_episode(is_manual=False)
                else:
                    xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Unknown action from countdown dialog: {action}", level=xbmc.LOGWARNING)
                    
            except Exception as e:
                xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error showing countdown dialog: {e}", level=xbmc.LOGERROR)
            
    def _handle_next_episode(self, is_manual=False):
        """Zpracuje přehrání další epizody z Kodi knihovny.

        Spustitelné pouze jednou současně - duplicitní volání (např. z více
        vláken při timeoutu countdownu) se ignorují. Souběh dvou stop() /
        PlayMedia() by shodil celé Kodi.
        """
        with self._next_episode_lock:
            if self._handling_next:
                xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Next episode already in progress, ignoring duplicate call", level=xbmc.LOGINFO)
                return
            self._handling_next = True

        try:
            # Získání informací o další epizodě
            next_episode = self.autoplay_manager.get_next_episode_info()
            if not next_episode:
                xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: No next episode found", level=xbmc.LOGINFO)
                if not is_manual:  # Zobrazit notifikaci pouze při automatickém autoplay
                    xbmcgui.Dialog().notification(
                        "Autoplay",
                        "Žádná další epizoda nebyla nalezena",
                        xbmcgui.NOTIFICATION_WARNING,
                        3000
                    )
                return

            # Získání informací o současném seriálu
            current_series = self.autoplay_manager.current_series_info
            if not current_series:
                xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: No current series info", level=xbmc.LOGWARNING)
                return

            series_name = current_series['name']
            next_season = next_episode['season']
            next_episode_num = next_episode['episode']
            tmdb_id = current_series.get('tmdb_id', '')

            # Sestavení URL pro přehrání další epizody z knihovny
            addon = xbmcaddon.Addon()

            play_url = (
                f"plugin://{addon.getAddonInfo('id')}?"
                f"action=play_episode_from_library&"
                f"series_name={quote_plus(series_name)}&"
                f"season={next_season}&"
                f"episode={next_episode_num}&"
                f"autoplay_request=true"
            )

            # Přidat TMDb ID pokud je dostupné
            if tmdb_id:
                play_url += f"&tmdb_id={tmdb_id}"

            xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Playing next episode - {series_name} S{next_season:02d}E{next_episode_num:02d}", level=xbmc.LOGINFO)

            # Nastavení informací o nové epizodě v AutoplayManager
            self.autoplay_manager.set_current_episode(series_name, next_season, next_episode_num, tmdb_id)

            # Zastavení současného přehrávání
            self.stop()

            # Počkat, až přehrávání opravdu skončí (max ~3 s) - teprve potom
            # spustit další díl. Pevné sleep() ani duplicitní PlayMedia() zde
            # nesmí být, jinak hrozí souběh a pád Kodi.
            for _ in range(30):
                if not self.isPlaying():
                    break
                time.sleep(0.1)

            # Spuštění další epizody (právě jednou - viz guard výše)
            xbmc.executebuiltin(f'PlayMedia({play_url})')

            xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Next episode playback initiated", level=xbmc.LOGINFO)

        except Exception as e:
            xbmc.log(f"[plugin.video.wcs] AutoplayPlayerMonitor: Error handling next episode: {e}", level=xbmc.LOGERROR)
            traceback.print_exc()

            # Zobrazení chybové notifikace uživateli
            if not is_manual:  # Chybu zobrazit pouze při automatickém přehrání
                xbmcgui.Dialog().notification(
                    "Autoplay - Chyba",
                    "Nepodařilo se spustit další epizodu",
                    xbmcgui.NOTIFICATION_ERROR,
                    3000
                )
        finally:
            with self._next_episode_lock:
                self._handling_next = False

        # Zastavení monitoring
        self._stop_monitoring()

# Globální instance player monitoru
_player_monitor = None

def get_player_monitor():
    """Vrátí globální instanci player monitoru."""
    global _player_monitor
    if _player_monitor is None:
        _player_monitor = AutoplayPlayerMonitor()
        xbmc.log("[plugin.video.wcs] AutoplayPlayerMonitor: Created singleton instance", level=xbmc.LOGINFO)
    return _player_monitor

def start_autoplay_monitoring():
    """Spustí autoplay monitoring."""
    monitor = get_player_monitor()
    return monitor

def stop_autoplay_monitoring():
    """Zastaví autoplay monitoring."""
    global _player_monitor
    if _player_monitor:
        _player_monitor._stop_monitoring()
        # Nemazeme instanci - singleton zůstává

# POZNÁMKA: Odstranil jsem automatickou registraci při importu
# Monitor se nyní spustí pouze při potřebě přes get_player_monitor() 