# wcs/player_monitor.py

import os
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
import threading
import time

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


# --- File-based lock pro cross-process koordinaci (issue 001 fix) ---
def _get_lock_dir():
    """Vrátí cestu k adresáři pro file-based locky."""
    addon = xbmcaddon.Addon()
    profile = xbmcvfs.translatePath(addon.getAddonInfo('profile'))
    lock_dir = os.path.join(profile, '_autoplay_locks')
    os.makedirs(lock_dir, exist_ok=True)
    return lock_dir

def _acquire_lock(name, ttl=30):
    """Pokusí se získat file-based lock. Vrací True pokud úspěšný."""
    lock_file = os.path.join(_get_lock_dir(), f'{name}.lock')
    tid = threading.current_thread().ident
    try:
        if os.path.exists(lock_file):
            # Kontrola TTL
            age = time.time() - os.path.getmtime(lock_file)
            if age < ttl:
                xbmc.log(f"[plugin.video.wcs] [T:{tid}] Lock '{name}': BLOCKED (age={age:.1f}s)", level=xbmc.LOGINFO)
                return False
            else:
                xbmc.log(f"[plugin.video.wcs] [T:{tid}] Lock '{name}': STALE (age={age:.1f}s), removing", level=xbmc.LOGWARNING)
                os.remove(lock_file)
        with open(lock_file, 'w') as f:
            f.write(str(tid))
        xbmc.log(f"[plugin.video.wcs] [T:{tid}] Lock '{name}': ACQUIRED", level=xbmc.LOGINFO)
        return True
    except Exception as e:
        xbmc.log(f"[plugin.video.wcs] [T:{tid}] Lock '{name}': ERROR: {e}", level=xbmc.LOGERROR)
        return False

def _release_lock(name):
    """Uvolní file-based lock."""
    lock_file = os.path.join(_get_lock_dir(), f'{name}.lock')
    tid = threading.current_thread().ident
    try:
        if os.path.exists(lock_file):
            os.remove(lock_file)
        xbmc.log(f"[plugin.video.wcs] [T:{tid}] Lock '{name}': RELEASED", level=xbmc.LOGINFO)
    except Exception as e:
        xbmc.log(f"[plugin.video.wcs] [T:{tid}] Lock '{name}': RELEASE ERROR: {e}", level=xbmc.LOGWARNING)

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
        
        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."""
        tid = threading.current_thread().ident
        xbmc.log(f"[plugin.video.wcs] [T:{tid}] >>> _handle_test_playback_start: ENTER", level=xbmc.LOGINFO)
        
        # File-based lock pro cross-process koordinaci (issue 001)
        if not _acquire_lock('info_dialog'):
            xbmc.log(f"[plugin.video.wcs] [T:{tid}] _handle_test_playback_start: BLOCKED by lock, skipping", level=xbmc.LOGINFO)
            return
        
        try:
            # Kratší pauza pro rychlejší zobrazení episode info dialogu
            xbmc.sleep(3000)  # issue 001: xbmc.sleep místo time.sleep
            
            if self.isPlaying():
                try:
                    self.total_time = self.getTotalTime()
                    xbmc.log(f"[plugin.video.wcs] [T:{tid}] 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
                    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(f"[plugin.video.wcs] [T:{tid}] 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] [T:{tid}] AutoplayPlayerMonitor: Error in _handle_test_playback_start: {e}", level=xbmc.LOGERROR)
        finally:
            _release_lock('info_dialog')
            xbmc.log(f"[plugin.video.wcs] [T:{tid}] <<< _handle_test_playback_start: EXIT", level=xbmc.LOGINFO)
    
    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
                xbmc.sleep(1000)  # issue 001: xbmc.sleep místo time.sleep
                
            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."""
        tid = threading.current_thread().ident
        
        # File-based lock pro cross-process koordinaci (issue 001)
        if not _acquire_lock('next_episode'):
            xbmc.log(f"[plugin.video.wcs] [T:{tid}] _handle_next_episode: BLOCKED by lock, skipping", level=xbmc.LOGINFO)
            return
        
        try:
            # Získání informací o další epizodě
            next_episode = self.autoplay_manager.get_next_episode_info()
            if not next_episode:
                xbmc.log(f"[plugin.video.wcs] [T:{tid}] AutoplayPlayerMonitor: No next episode found", level=xbmc.LOGINFO)
                if not is_manual:
                    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(f"[plugin.video.wcs] [T:{tid}] 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
            import xbmcaddon
            addon = xbmcaddon.Addon()
            from urllib.parse import quote_plus
            
            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"
            )
            
            if tmdb_id:
                play_url += f"&tmdb_id={tmdb_id}"
                
            xbmc.log(f"[plugin.video.wcs] [T:{tid}] 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()
            
            # Malé zpoždění pro stabilitu
            xbmc.sleep(500)  # issue 001: xbmc.sleep místo time.sleep
            
            # Spuštění další epizody
            xbmc.executebuiltin(f'PlayMedia({play_url})')
            
            xbmc.log(f"[plugin.video.wcs] [T:{tid}] AutoplayPlayerMonitor: Next episode playback initiated", level=xbmc.LOGINFO)
            
        except Exception as e:
            xbmc.log(f"[plugin.video.wcs] [T:{tid}] AutoplayPlayerMonitor: Error handling next episode: {e}", level=xbmc.LOGERROR)
            import traceback
            traceback.print_exc()
            
            if not is_manual:
                xbmcgui.Dialog().notification(
                    "Autoplay - Chyba", 
                    "Nepodařilo se spustit další epizodu",
                    xbmcgui.NOTIFICATION_ERROR,
                    3000
                )
        finally:
            _release_lock('next_episode')
        
        # 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() 