# wcs/utils.py

import re
import math # Potřebné pro log
import difflib
from urllib.parse import quote_plus # <-- PŘIDÁN POTŘEBNÝ IMPORT
from wcs import user_data # <-- PŘIDÁN IMPORT PRO KONTROLU PŘIHLÁŠENÍ

# === SDÍLENÉ FUNKCE PRO EXTRAKCI METADAT (pro filmy i seriály) ===

def extract_clean_title(filename):
    """Extrahuje čitelný název filmu z technického názvu souboru."""
    # Odstraň příponu
    clean_name = re.sub(r'\.[^.]+$', '', filename)
    
    # Odstraň epizody označení (E01, E04 atd.)
    clean_name = re.sub(r'(?i)\bE\d+\.?\s*', '', clean_name)
    
    # Odstraň technické detaily (rozlišení, formáty, kodeky)
    clean_name = re.sub(r'(?i)\b(1080p|720p|480p|360p|2160p|4k|uhd)\b', '', clean_name)
    clean_name = re.sub(r'(?i)\b(x264|x265|hevc|h\.264|h\.265)\b', '', clean_name)
    clean_name = re.sub(r'(?i)\b(bluray|brrip|web-dl|hdtv|webrip|remux|proper|remastered|bd|hb|enc)\b', '', clean_name)
    clean_name = re.sub(r'(?i)\b(dd5\.1|dts|ac3|aac|mp3|flac)\b', '', clean_name)
    clean_name = re.sub(r'(?i)\b(hdr|hdr10|dolby\.vision)\b', '', clean_name)
    
    # Odstraň čísla verzí/kanálů (5.1, 7.1 atd.)
    clean_name = re.sub(r'\b\d+\.\d+\b', '', clean_name)
    
    # Odstraň jazykové značky a speciální znaky
    clean_name = re.sub(r'(?i)\b(cz|czech|en|english|sk|slovak|multidub|czen|cz-eng)\b', '', clean_name)
    clean_name = re.sub(r'(?i)\b(dabing|titulky|dub|sub)\b', '', clean_name)
    clean_name = re.sub(r'[,()]+\s*$', '', clean_name)  # Odstraň závěrečné čárky a závorky
    
    # Odstraň group tagy (obvykle na konci)
    clean_name = re.sub(r'-[A-Z0-9]+$', '', clean_name)
    
    # Nahraď tečky a podtržítka mezerami
    clean_name = re.sub(r'[._-]', ' ', clean_name)
    
    # Odstraň extra mezery a speciální znaky
    clean_name = re.sub(r'[,()]+', '', clean_name)  # Odstraň čárky a závorky
    clean_name = re.sub(r'\s+', ' ', clean_name).strip()
    
    # Pokus o extrakci roku a přesun na konec
    year_match = re.search(r'\b(19\d{2}|20\d{2})\b', clean_name)
    if year_match:
        year = year_match.group(1)
        clean_name = re.sub(r'\b(19\d{2}|20\d{2})\b', '', clean_name).strip()
        clean_name = f"{clean_name} ({year})"
    
    # Odstraň extra mezery znovu
    clean_name = re.sub(r'\s+', ' ', clean_name).strip()
    
    # Kapitalizace prvních písmen slov
    clean_name = ' '.join(word.capitalize() for word in clean_name.split() if word)
    
    return clean_name if clean_name else filename

def extract_quality(filename):
    """Extrahuje kvalitu z názvu souboru."""
    if not filename:
        return 'SD'
    
    filename_lower = filename.lower()
    
    # REMUX má nejvyšší prioritu, ale jen u velkých souborů
    if 'remux' in filename_lower:
        return 'REMUX'
    
    # Rozlišení - OPRAVA: Hledáme i s tečkami a jinými znaky
    if re.search(r'2160p|4k|uhd', filename_lower):
        return '4K'
    elif re.search(r'1080p', filename_lower):  # OPRAVA: Použijeme re.search místo 'in'
        return '1080p'  
    elif re.search(r'720p', filename_lower):
        return '720p'
    elif re.search(r'480p', filename_lower):
        return '480p'
    elif re.search(r'360p', filename_lower):
        return '360p'
    elif re.search(r'\bhd\b', filename_lower):
        return 'HD'  # HD také považujeme za detekovanou kvalitu
    
    return 'SD'

def extract_language(filename):
    """Extrahuje jazyk/dabing z názvu souboru."""
    filename_lower = filename.lower()
    
    if re.search(r'cz.*dabing|czech.*dub', filename_lower):
        return 'CZ Dab'
    elif 'multidub' in filename_lower:
        return 'MultiDub'  
    elif 'czen' in filename_lower or 'cz-eng' in filename_lower:
        return 'CZ+EN'
    elif re.search(r'\.cz\.|\.cz$|cz\.', filename_lower):  # OPRAVA: Hledáme i s tečkami
        return 'CZ'
    elif re.search(r'\bcz\b', filename_lower):  # Původní word boundary
        return 'CZ'
    elif 'slovak' in filename_lower or re.search(r'\bsk\b', filename_lower):
        return 'SK'
    elif 'english' in filename_lower or re.search(r'\ben\b', filename_lower):
        return 'EN'
    
    return 'N/A'

def extract_format(filename):
    """Extrahuje formát souboru."""
    if filename.lower().endswith('.mkv'):
        return 'MKV'
    elif filename.lower().endswith('.mp4'):
        return 'MP4'
    elif filename.lower().endswith('.avi'):
        return 'AVI'
    elif filename.lower().endswith('.mov'):
        return 'MOV'
    
    return 'N/A'

def calculate_rating(item):
    """Vypočítá user rating jako pozitivní/negativní hlasy."""
    try:
        positive = int(item.get('positive_votes', 0))
        negative = int(item.get('negative_votes', 0))
        if positive == 0 and negative == 0:
            return "0+/0-"
        return f"{positive}+/{negative}-"
    except (ValueError, TypeError):
        return "0+/0-"

def calculate_advanced_score(item, original_query):
    """
    SDÍLENÉ pokročilé skórování pro filmy i seriály s prioritou: 1. kvalita, 2. velikost, 3. CZ jazyk.
    
    Args:
        item (dict): Webshare soubor s 'name', 'size', atd.
        original_query (str): Původní vyhledávací dotaz
        
    Returns:
        int: Celkové skóre pro řazení (vyšší = lepší)
    """
    filename = item.get('name', '')
    name = filename.lower()
    query_lower = original_query.lower()
    
    # === ZÁKLADNÍ SHODA NÁZVU (0-1000 bodů) ===
    base_score = 0
    if query_lower in name:
        base_score = 1000
    else:
        similarity_score = int(difflib.SequenceMatcher(None, query_lower, name).ratio() * 700)
        base_score = similarity_score
    
    # === 1. PRIORITA: KVALITA VIDEA (0-50000 bodů) - každá kvalita má vlastní skupinu ===
    quality_score = 0
    if 'remux' in name and int(item.get('size', 0)) > 15 * 1024**3:  # REMUX s velikostí 15GB+
        quality_score = 50000  # Nejvyšší kvalita
    elif re.search(r'2160p|4k|uhd', name):
        quality_score = 40000  # 4K
    elif '1080p' in name:
        quality_score = 30000  # 1080p
    elif re.search(r'\bhd\b', name):
        quality_score = 20000  # HD kvalita
    elif '720p' in name:
        quality_score = 15000  # 720p
    elif '480p' in name:
        quality_score = 10000  # 480p
    elif '360p' in name:
        quality_score = 5000   # 360p
    else:
        quality_score = 0      # SD/ostatní
    
    # === 2. PRIORITA: VELIKOST SOUBORU (0-3000 bodů) - v rámci kvality, větší = lepší ===
    size_score = 0
    try:
        size_bytes = int(item.get('size', 0))
        if size_bytes > 0:
            # Logaritmické škálování velikosti s vyšším maximem pro lepší rozlišení
            if size_bytes >= 100 * 1024**3:   # 100GB+
                size_score = 3000
            elif size_bytes >= 50 * 1024**3:  # 50GB+
                size_score = 2700
            elif size_bytes >= 30 * 1024**3:  # 30GB+
                size_score = 2400
            elif size_bytes >= 20 * 1024**3:  # 20GB+
                size_score = 2100
            elif size_bytes >= 15 * 1024**3:  # 15GB+
                size_score = 1800
            elif size_bytes >= 10 * 1024**3:  # 10GB+
                size_score = 1500
            elif size_bytes >= 8 * 1024**3:   # 8GB+
                size_score = 1200
            elif size_bytes >= 5 * 1024**3:   # 5GB+
                size_score = 900
            elif size_bytes >= 3 * 1024**3:   # 3GB+
                size_score = 600
            elif size_bytes >= 1 * 1024**3:   # 1GB+
                size_score = 300
            else:                              # < 1GB
                size_score = 100
    except (ValueError, TypeError):
        size_score = 0
    
    # === 3. PRIORITA: CZ JAZYK (0-500 bodů) ===
    cz_score = 0
    if re.search(r'cz.*dabing|czech.*dub', name):
        cz_score = 500  # CZ dabing = nejvyšší
    elif 'multidub' in name:
        cz_score = 400  # MultiDub
    elif 'czen' in name or 'cz-eng' in name:
        cz_score = 350  # CZ+EN
    elif re.search(r'\bcz\b|\.cz\.|\.cz$', name):
        cz_score = 300  # Obecné CZ (včetně .cz. a .cz na konci)
    elif 'slovak' in name or re.search(r'\bsk\b', name):
        cz_score = 200  # SK
    else:
        cz_score = 0    # Ostatní jazyky
    
    # === BONUSY ZA KVALITNÍ KODEKY A FORMÁTY (0-200 bodů) ===
    bonus_score = 0
    if 'hdr' in name:
        bonus_score += 100
    if re.search(r'x265|hevc', name):
        bonus_score += 50
    if 'bluray' in name:
        bonus_score += 30
    if name.endswith('.mkv'):
        bonus_score += 20
    
    # === FINÁLNÍ SKÓRE ===
    final_score = base_score + quality_score + size_score + cz_score + bonus_score
    
    return final_score

# === POMOCNÉ FUNKCE PRO FORMÁTOVÁNÍ ===

def is_valid_file_size(quality, size_bytes):
    """
    Kontroluje zda má soubor odpovídající velikost pro danou kvalitu.
    Malé soubory (trailery, ukázky) se odfiltrují.
    """
    try:
        size_bytes = int(size_bytes) if size_bytes else 0
    except (ValueError, TypeError):
        return False
    
    # Minimální velikosti pro jednotlivé kvality
    size_limits = {
        'REMUX': 100 * 1024**2,    # 100 MB
        '4K': 100 * 1024**2,       # 100 MB  
        '1080p': 100 * 1024**2,    # 100 MB
        '720p': 100 * 1024**2,     # 100 MB
        '480p': 100 * 1024**2,     # 100 MB
        '360p': 100 * 1024**2,     # 100 MB
        'SD': 100 * 1024**2        # 100 MB
    }
    
    min_size = size_limits.get(quality, 100 * 1024**2)  # Fallback 100 MB
    return size_bytes >= min_size

# Převod velikosti souboru na čitelný formát
def format_size(size_bytes):
    """Formátuje velikost souboru do lidsky čitelné formy."""
    if size_bytes is None or size_bytes == '' or size_bytes == '0':
        return 'N/A'
    
    try:
        size_bytes = int(size_bytes)
    except (ValueError, TypeError):
        return 'N/A'
    
    if size_bytes <= 0:
        return 'N/A'
    
    if size_bytes >= 1024**3:  # GB
        return f"{size_bytes / (1024**3):.1f} GB"
    elif size_bytes >= 1024**2:  # MB
        return f"{size_bytes / (1024**2):.0f} MB"
    else:
        return f"{size_bytes / 1024:.0f} KB"



# Extrakce čísla sezóny a epizody z názvu souboru (verze z router.py)
def extract_season_episode(filename):
    pattern1 = re.compile(r"[Ss](\d+)[Ee](\d+)")  # S01E01 nebo s01e01
    pattern2 = re.compile(r"(\d+)[Xx](\d+)")      # 1x01
    match = pattern1.search(filename)
    if match:
        return (int(match.group(1)), int(match.group(2)))
    match = pattern2.search(filename)
    if match:
        return (int(match.group(1)), int(match.group(2)))
    return (None, None) # Vrátí None, None pokud nenalezeno

# Řazení epizod podle sezóny a čísla epizody
def sort_episode_order(file_item):
    season, episode = extract_season_episode(file_item['name'])
    return (season, episode)

# Spojení cesty a názvu souboru
def join(path, file):
    if path.endswith('/') or path.endswith('\\'):
        return path + file
    else:
        return path + '/' + file 

# Získání roku vydání filmu pro řazení
def get_year_movie(movie):
    y = movie.get('release_date', '')[:4]
    try:
        return int(y)
    except ValueError:
        return 0 # Přiřadí 0 položkám bez platného roku

# Získání roku vydání seriálu pro řazení
def get_year_series(series):
    y = series.get('first_air_date', '')[:4]
    try:
        return int(y)
    except ValueError:
        return 0 # Přiřadí 0 položkám bez platného roku 

def sanitize_filename(filename):
    """Odstraní neplatné znaky pro názvy souborů/složek."""
    # Odstraní znaky, které nejsou povoleny v názvech souborů Windows/Linux/Mac
    sanitized = re.sub(r'[<>:"/\\|?*]', '', filename)
    # Nahradí více mezer jednou
    sanitized = re.sub(r'\\s+', ' ', sanitized).strip()
    # Můžeme přidat další specifické úpravy podle potřeby
    return sanitized 

def search_and_select_movie_file(title, year, plot='', poster='', fanart='', rating='', genre='', director='', runtime='', addon=None, tmdb_id=None, from_library=False, manual_search=False, autoplay=False):
    """
    WRAPPER: Tenký wrapper pro centrální funkci search_and_select_movie_file.
    Vrací vybraný soubor (dict) nebo None.
    """
    if not addon:
        import xbmcaddon
        addon = xbmcaddon.Addon()

    # Pokud některé metadata chybí, pokusíme se je získat z knihovny
    if not (plot and poster and fanart and rating and genre and director and runtime):
        try:
            from wcs.library.LibraryManager import get_movie_metadata_from_library
            metadata = get_movie_metadata_from_library(title, year) or {}
            plot = plot or metadata.get('plot', '')
            # Preferuj 'poster', fallback na 'thumb'
            poster = poster or metadata.get('poster', '') or metadata.get('thumb', '')
            fanart = fanart or metadata.get('fanart', '')
            rating = rating or str(metadata.get('rating', ''))
            genre = genre or metadata.get('genre', '')
            director = director or metadata.get('director', '')
            runtime = runtime or metadata.get('runtime', '')
        except Exception as e:
            import xbmc
            xbmc.log(f"[plugin.video.milionar] search_and_select_movie_file: Error getting metadata: {e}", level=xbmc.LOGWARNING)

    query = f"{title} {year}".strip()
    from wcs.ui.dialogs.DialogWcsSearch import show_search_dialog
    return show_search_dialog(
        search_query=query,
        movie_title=title,
        movie_year=year,
        poster_url=poster,
        rating=rating,
        genre=genre,
        director=director,
        runtime=runtime,
        plot=plot,
        fanart_url=fanart,
        search_results=[],
        is_episode=False,
        autoplay_request=autoplay
    )

def play_movie_from_addon(meta: dict, addon=None, autoplay=False):
    """JEDNOTNÝ vstup pro přehrání filmu z doplňku (Details, MyList, menu).

    Očekává meta s klíči: title, year, plot, poster, fanart, rating, genre,
    director, runtime. Data mají pocházet přímo ze seznamu/menu (cache),
    ne znovu tahat.
    """
    if not addon:
        import xbmcaddon
        addon = xbmcaddon.Addon()

    title = meta.get('title', '')
    year = meta.get('year', '')
    plot = meta.get('plot', '')
    poster = meta.get('poster', '')
    fanart = meta.get('fanart', '')
    rating = meta.get('rating', '')
    genre = meta.get('genre', '')
    director = meta.get('director', '')
    runtime = meta.get('runtime', '')

    def play_action():
        import xbmc
        from urllib.parse import quote_plus
        
        selected_file = search_and_select_movie_file(title, year, plot, poster, fanart, rating, genre, director, runtime, addon, autoplay=autoplay)
        
        if selected_file and 'ident' in selected_file and 'name' in selected_file:
            # Uložit do historie naposledy přehraných
            try:
                 item_data = {
                     'title': title,
                     'year': year,
                     'poster': poster,
                     'rating': rating,
                     'media_type': 'movie',
                     'tmdb_id': meta.get('tmdb_id'),
                     'plot': plot,
                     'genre': genre
                 }
                 user_data.add_recently_played_item(addon, item_data)
            except Exception as e:
                xbmc.log(f"[plugin.video.milionar] Error saving recently played movie: {e}", level=xbmc.LOGERROR)

            ident = selected_file['ident']
            name = selected_file['name']
            play_url = (f"plugin://{addon.getAddonInfo('id')}?action=play"
                       f"&ident={ident}"
                       f"&name={quote_plus(name)}"
                       f"&tmdb_title={quote_plus(title)}"
                       f"&tmdb_year={quote_plus(year) if year else ''}"
                       f"&tmdb_plot={quote_plus(plot) if plot else ''}"
                       f"&tmdb_thumb={quote_plus(poster) if poster else ''}"
                       f"&tmdb_fanart={quote_plus(fanart) if fanart else ''}"
                       f"&tmdb_rating={quote_plus(rating) if rating else ''}"
                       f"&tmdb_genre={quote_plus(genre) if genre else ''}"
                       f"&tmdb_director={quote_plus(director) if director else ''}"
                       f"&tmdb_runtime={quote_plus(runtime) if runtime else ''}")
            xbmc.log(f"[plugin.video.milionar] search_and_play_movie: Executing PlayMedia: {play_url}", level=xbmc.LOGINFO)
            
            xbmc.executebuiltin('Dialog.Close(all, true)')
            xbmc.executebuiltin(f'PlayMedia({play_url})')

            # Po spuštění přehrávání z doplňku zobraz filmový info dialog s TMDb daty
            # (stejné chování jako při přehrávání z knihovny, ale bez závislosti na Kodi knihovně)
            def _show_info_after_play():
                try:
                    import time
                    import xbmc
                    import xbmcaddon
                    # Počkat na start přehrávání (max ~10s)
                    for _ in range(100):
                        if xbmc.Player().isPlaying():
                            break
                        time.sleep(0.1)
                    else:
                        return
                    # Krátké zpoždění pro stabilní zobrazení info dialogu
                    time.sleep(3)

                    # Respektuj nastavení zobrazování info dialogu
                    addon_local = xbmcaddon.Addon()
                    if not addon_local.getSettingBool('show_episode_info'):
                        return

                    # Zobraz MovieInfoDialog s dostupnými TMDb daty
                    from wcs.playback.DialogMediaInfoWithGame import get_movie_info_manager
                    movie_info_manager = get_movie_info_manager()

                    # Normalizace hodnocení: očekává se pouze číselná hodnota (např. "8.1")
                    rating_clean = ""
                    try:
                        import re as _re
                        rating_text = str(rating) if rating is not None else ""
                        match = _re.search(r"\d+(?:[\.,]\d+)?", rating_text)
                        if match:
                            rating_clean = match.group(0).replace(',', '.')
                    except Exception:
                        rating_clean = str(rating) if rating else ""
                    movie_info_manager.show_movie_info(
                        movie_title=title,
                        movie_year=year or "",
                        movie_thumb=poster or "",
                        rating=rating_clean,
                        plot=plot or "",
                        tmdb_id="",
                        fanart=fanart or "",
                        genre=genre or "",
                        director=director or "",
                        runtime=runtime or ""
                    )
                except Exception as e:
                    import xbmc as _xbmc
                    _xbmc.log(f"[plugin.video.milionar] Movie info (plugin playback) error: {e}", level=_xbmc.LOGWARNING)

            import threading as _threading
            _threading.Thread(target=_show_info_after_play, daemon=True).start()
        else:
            xbmc.log("[plugin.video.milionar] search_and_play_movie: No file selected or search failed", level=xbmc.LOGINFO)

    user_data._check_credentials_and_prompt(addon, on_success_callback=play_action)


# Zachovat původní API pro stávající volání – převede argumenty do meta a volá jednotnou funkci
def search_and_play_movie(title, year, plot='', poster='', fanart='', rating='', genre='', director='', runtime='', addon=None, autoplay=False):
    meta = {
        'title': title,
        'year': year,
        'plot': plot,
        'poster': poster,
        'fanart': fanart,
        'rating': rating,
        'genre': genre,
        'director': director,
        'runtime': runtime,
    }
    return play_movie_from_addon(meta, addon, autoplay=autoplay)

def search_and_play_episode(series_name, season, episode, ep_name, plot='', poster='', fanart='', rating='', genre='', addon=None, year='', runtime='', tmdb_id=''):
    """
    Funkce pro vyhledání a přehrání epizody z doplňku - používá PlayMedia().
    """
    if not addon:
        import xbmcaddon
        addon = xbmcaddon.Addon()

    def play_action():
        import xbmc
        from urllib.parse import quote_plus

        selected_file = search_and_select_episode_file(series_name, season, episode, ep_name, plot, poster, fanart, rating, genre, addon, year, runtime)
        
        if selected_file and 'ident' in selected_file and 'name' in selected_file:
            # Uložit do historie naposledy přehraných
            try:
                 item_data = {
                     'title': series_name, # Pro seriál ukládáme jméno seriálu jako hlavní titulek
                     'episode_title': ep_name or f"S{season:02d}E{episode:02d}", # K tomu detail epizody
                     'year': year,
                     'poster': poster,
                     'rating': rating,
                     'media_type': 'series',
                     'tmdb_id': tmdb_id,
                     'season': season,
                     'episode': episode,
                     'plot': plot,
                     'genre': genre
                 }
                 user_data.add_recently_played_item(addon, item_data)
            except Exception as e:
                xbmc.log(f"[plugin.video.milionar] Error saving recently played episode: {e}", level=xbmc.LOGERROR)

            ident = selected_file['ident']
            name = selected_file['name']
            play_url = (f"plugin://{addon.getAddonInfo('id')}?action=play"
                       f"&ident={ident}"
                       f"&name={quote_plus(name)}"
                       f"&tmdb_title={quote_plus(f'{series_name} S{season:02d}E{episode:02d}')}"
                       f"&tmdb_plot={quote_plus(plot) if plot else ''}"
                       f"&tmdb_thumb={quote_plus(poster) if poster else ''}"
                       f"&tmdb_fanart={quote_plus(fanart) if fanart else ''}"
                       f"&tmdb_rating={quote_plus(rating) if rating else ''}"
                       f"&tmdb_genre={quote_plus(genre) if genre else ''}"
                       f"&tmdb_season={season}"
                       f"&tmdb_episode={episode}"
                       f"&tmdb_series_name={quote_plus(series_name)}"
                       f"&tmdb_year={quote_plus(year) if year else ''}"
                       f"&tmdb_runtime={quote_plus(runtime) if runtime else ''}")
            xbmc.log(f"[plugin.video.milionar] search_and_play_episode: Executing PlayMedia: {play_url}", level=xbmc.LOGINFO)
            
            xbmc.executebuiltin('Dialog.Close(all, true)')
            xbmc.executebuiltin(f'PlayMedia({play_url})')

            # Plánované zobrazení epizodního info dialogu po startu přehrávání
            schedule_episode_info_dialog(
                series_name=series_name,
                episode_title=ep_name or f"Epizoda {episode}",
                season_number=season,
                episode_number=episode,
                poster=poster,
                fanart=fanart,
                rating=rating,
                year=year,
                plot=plot,
                tmdb_id=tmdb_id
            )
        else:
            xbmc.log("[plugin.video.milionar] search_and_play_episode: No file selected or search failed", level=xbmc.LOGINFO)

    user_data._check_credentials_and_prompt(addon, on_success_callback=play_action)


def schedule_episode_info_dialog(series_name, episode_title, season_number, episode_number, poster='', fanart='', rating='', year='', plot='', tmdb_id=''):
    """Naplánuje zobrazení EpisodeInfoDialog po detekci startu přehrávání.

    Používá stejné nastavení a normalizaci jako filmový hook; sdílené pro
    různé toky (MyList, TMDb menu).
    """
    import threading
    
    def _worker():
        try:
            import time
            import xbmc
            import xbmcaddon
            # Počkat na start přehrávání (max ~10s)
            for _ in range(100):
                if xbmc.Player().isPlaying():
                    break
                time.sleep(0.1)
            else:
                return
            time.sleep(3)
            # Respektovat nastavení
            addon_local = xbmcaddon.Addon()
            if not addon_local.getSettingBool('show_episode_info'):
                return
            # Normalizace ratingu
            rating_clean = ""
            try:
                import re as _re
                rating_text = str(rating) if rating is not None else ""
                m = _re.search(r"\d+(?:[\.,]\d+)?", rating_text)
                if m:
                    rating_clean = m.group(0).replace(',', '.')
            except Exception:
                rating_clean = str(rating) if rating else ""
            # Obrázek epizody bereme PŘESNĚ tak, jak byl předán z menu (bez fallbacku).
            # Preferuj speciální property z TMDb menu: tmdb_episode_thumb → jinak 'poster'.
            episode_thumb = poster or ""

            # Zobrazení dialogu
            from wcs.playback.DialogMediaInfoWithGame import get_episode_info_manager
            episode_info_manager = get_episode_info_manager()
            episode_info_manager.show_episode_info(
                series_name=series_name,
                episode_title=episode_title or (f"Epizoda {episode_number}" if episode_number else ""),
                season_number=season_number,
                episode_number=episode_number,
                episode_thumb=episode_thumb,
                rating=rating_clean,
                year=year or "",
                plot=plot or "",
                tmdb_id=str(tmdb_id) if tmdb_id else "",
                fanart=fanart or ""
            )
        except Exception as e:
            import xbmc as _xbmc
            _xbmc.log(f"[plugin.video.milionar] schedule_episode_info_dialog error: {e}", level=_xbmc.LOGWARNING)
    
    threading.Thread(target=_worker, daemon=True).start()


def play_episode_from_addon(meta: dict, addon=None):
    """JEDNOTNÝ vstup pro přehrání epizody ze doplňku (TMDb menu, MyList).

    Očekává meta s klíči (z menu/cache, bez síťových dotazů):
      - series_name, season_number, episode_number, episode_title
      - poster (poster seriálu pro UI), fanart (serióvý fanart)
      - episode_thumb (still epizody pro úvodní dialog)
      - plot, rating, genre, year, runtime, tmdb_id
    """
    if not addon:
        import xbmcaddon
        addon = xbmcaddon.Addon()

    series_name = meta.get('series_name', '')
    season_number = int(meta.get('season_number') or 0)
    episode_number = int(meta.get('episode_number') or 0)
    episode_title = meta.get('episode_title', '')
    poster = meta.get('poster', '')            # poster seriálu pro UI
    fanart = meta.get('fanart', '')            # fanart seriálu
    episode_thumb = meta.get('episode_thumb', '')  # still epizody pro úvodní dialog
    plot = meta.get('plot', '')
    rating = meta.get('rating', '')
    genre = meta.get('genre', '')
    year = meta.get('year', '')
    runtime = meta.get('runtime', '')
    tmdb_id = meta.get('tmdb_id', '')

    def play_action():
        import xbmc
        from urllib.parse import quote_plus

        # 1) Vyhledání a výběr souboru přes náš sjednocený Search dialog
        search_str = f"{series_name} S{season_number:02d}E{episode_number:02d}"
        from wcs.ui.dialogs.DialogWcsSearch import show_search_dialog
        selected_file = show_search_dialog(
            search_query=search_str,
            movie_title=(f"{series_name} – {episode_title}" if episode_title else series_name),
            movie_year=year,
            poster_url=poster,          # UI poster = poster seriálu
            fanart_url=fanart,
            rating=rating,
            genre=genre,
            runtime=runtime,
            plot=plot,
            is_episode=True,
            series_name=series_name,
            season_number=season_number,
            episode_number=episode_number,
            tmdb_id=tmdb_id,
            episode_title=episode_title or (f"Epizoda {episode_number}" if episode_number else ''),
            episode_thumb=episode_thumb,   # still epizody pouze pro úvodní dialog
            from_library=False,
        )

        # 2) Spuštění PlayMedia s plugin:// action=play
        if selected_file and 'ident' in selected_file:
            ident = selected_file['ident']
            name = selected_file.get('name', '')
            play_url = (
                f"plugin://{addon.getAddonInfo('id')}?action=play"
                f"&ident={ident}"
                f"&name={quote_plus(name)}"
                f"&tmdb_title={quote_plus(f'{series_name} S{season_number:02d}E{episode_number:02d}') }"
                f"&tmdb_plot={quote_plus(plot) if plot else ''}"
                f"&tmdb_thumb={quote_plus(poster) if poster else ''}"
                f"&tmdb_fanart={quote_plus(fanart) if fanart else ''}"
                f"&tmdb_rating={quote_plus(rating) if rating else ''}"
                f"&tmdb_genre={quote_plus(genre) if genre else ''}"
                f"&tmdb_season={season_number}"
                f"&tmdb_episode={episode_number}"
                f"&tmdb_series_name={quote_plus(series_name)}"
                f"&tmdb_year={quote_plus(year) if year else ''}"
                f"&tmdb_runtime={quote_plus(runtime) if runtime else ''}"
            )

            xbmc.executebuiltin('Dialog.Close(all, true)')
            xbmc.executebuiltin(f'PlayMedia({play_url})')
            # POZN: Úvodní epizodní dialog se plánuje v SearchDialogu (mimo knihovnu),
            # zde ho už znovu NEPLÁNUJEME, aby nedošlo k duplikaci.

    user_data._check_credentials_and_prompt(addon, on_success_callback=play_action)

def search_and_select_episode_file(series_name, season, episode, ep_name, plot='', poster='', fanart='', rating='', genre='', addon=None, year='', runtime=''):
    """
    WRAPPER: Tenký wrapper pro centrální funkci search_and_select_series_file.
    Vrací vybraný soubor (dict) nebo None.
    """
    if not addon:
        import xbmcaddon
        addon = xbmcaddon.Addon()

    search_str = f"{series_name} S{season:02d}E{episode:02d}"
    
    # OPRAVA: Vždy používat search_dialog.py pro jednotnou logiku
    from wcs.ui.dialogs.DialogWcsSearch import show_search_dialog
    
    # Pokud už je ep_name ve formátu "Název seriálu – Název epizody", použijeme ho přímo
    if ep_name and " – " in ep_name:
        movie_title = ep_name
    elif ep_name and ep_name != f"Epizoda {episode}":
        movie_title = f"{series_name} – {ep_name}"
    else:
        movie_title = series_name
    
    return show_search_dialog(
        search_query=search_str,
        movie_title=movie_title,
        movie_year=year,
        poster_url=poster,
        fanart_url=fanart,
        rating=rating,
        genre=genre,
        director='',
        runtime=runtime,
        plot=plot,
        search_results=[],
        is_episode=True,
        series_name=series_name,
        season_number=season,
        episode_number=episode,
        episode_title=ep_name
    )

def resolve_movie_for_library(title, year, addon, handle):
    """
    Funkce pro přehrání filmu z knihovny Kodi - používá setResolvedUrl().
    """
    import xbmc
    import xbmcgui
    import xbmcplugin
    from wcs.webshare import WebshareClient as webshare_api

    # Použití STEJNÉ JEDINÉ funkce pro výběr souboru
    selected_file = search_and_select_movie_file(title, year, '', '', '', '', '', '', '', addon)

    if selected_file and 'ident' in selected_file:
        ident = selected_file.get('ident')
        
        # Získání tokenu
        token = webshare_api.revalidate(addon, lambda msg, title=None, icon=None: None)  # Tichý fallback
        if token:
            # Před přehráním z knihovny: zkontroluj VIP expiraci s varováním
            try:
                webshare_api.refresh_vip_info(addon, token_override=token, show_notification=False, log_context="library_movie", show_warning=True)
            except Exception:
                pass
            # Získání stream URL
            link = webshare_api.getlink(ident, token, dtype='video_stream', addon=addon)
            if link:
                # Úspěšné vyřešení
                listitem = xbmcgui.ListItem(path=link)
                listitem.setProperty('IsPlayable', 'true')
                xbmcplugin.setResolvedUrl(handle, True, listitem)
                xbmc.log(f"[plugin.video.milionar] resolve_movie_for_library: Successfully resolved: {selected_file.get('name', '')}", level=xbmc.LOGINFO)
                return

    # Selhání - vrátit prázdný resolve
    xbmc.log(f"[plugin.video.milionar] resolve_movie_for_library: Failed to resolve stream for '{title} {year}'", level=xbmc.LOGWARNING)
    xbmcplugin.setResolvedUrl(handle, False, xbmcgui.ListItem()) 

def set_video_info_tag(listitem, info_dict):
    """
    Univerzální funkce pro nastavování video info tagu místo zastaralé setInfo metody.
    Používá nové InfoTagVideo settery pro lepší výkon a kompatibilitu s budoucími verzemi Kodi.
    
    Args:
        listitem: xbmcgui.ListItem objekt
        info_dict: Slovník s video informacemi
    """
    if not info_dict:
        return
    
    video_tag = listitem.getVideoInfoTag()
    
    # Základní informace
    if 'title' in info_dict:
        video_tag.setTitle(str(info_dict['title']))
    if 'plot' in info_dict:
        video_tag.setPlot(str(info_dict['plot']))
    if 'plotoutline' in info_dict:
        video_tag.setPlotOutline(str(info_dict['plotoutline']))
    if 'year' in info_dict and info_dict['year']:
        try:
            video_tag.setYear(int(info_dict['year']))
        except (ValueError, TypeError):
            pass
    if 'originaltitle' in info_dict:
        video_tag.setOriginalTitle(str(info_dict['originaltitle']))
    if 'sorttitle' in info_dict:
        video_tag.setSortTitle(str(info_dict['sorttitle']))
    if 'tagline' in info_dict:
        video_tag.setTagLine(str(info_dict['tagline']))
    if 'mediatype' in info_dict:
        video_tag.setMediaType(str(info_dict['mediatype']))
    
    # Hodnocení a počty
    if 'rating' in info_dict and info_dict['rating']:
        try:
            video_tag.setRating(float(info_dict['rating']))
        except (ValueError, TypeError):
            pass
    if 'userrating' in info_dict and info_dict['userrating']:
        try:
            video_tag.setUserRating(int(info_dict['userrating']))
        except (ValueError, TypeError):
            pass
    if 'votes' in info_dict and info_dict['votes']:
        try:
            video_tag.setVotes(int(info_dict['votes']))
        except (ValueError, TypeError):
            pass
    if 'playcount' in info_dict and info_dict['playcount']:
        try:
            video_tag.setPlaycount(int(info_dict['playcount']))
        except (ValueError, TypeError):
            pass
    
    # Časy a data
    if 'duration' in info_dict and info_dict['duration']:
        try:
            video_tag.setDuration(int(info_dict['duration']))
        except (ValueError, TypeError):
            pass
    if 'premiered' in info_dict:
        video_tag.setPremiered(str(info_dict['premiered']))
    if 'aired' in info_dict:
        video_tag.setFirstAired(str(info_dict['aired']))
    if 'lastplayed' in info_dict:
        video_tag.setLastPlayed(str(info_dict['lastplayed']))
    if 'dateadded' in info_dict:
        video_tag.setDateAdded(str(info_dict['dateadded']))
    
    # Seriálové informace
    if 'episode' in info_dict and info_dict['episode']:
        try:
            video_tag.setEpisode(int(info_dict['episode']))
        except (ValueError, TypeError):
            pass
    if 'season' in info_dict and info_dict['season']:
        try:
            video_tag.setSeason(int(info_dict['season']))
        except (ValueError, TypeError):
            pass
    if 'tvshowtitle' in info_dict:
        video_tag.setTvShowTitle(str(info_dict['tvshowtitle']))
    
    # Seznamy (žánry, země, atd.)
    if 'genre' in info_dict:
        genres = info_dict['genre']
        if isinstance(genres, str):
            genres = [genres]
        elif isinstance(genres, list):
            genres = [str(g) for g in genres if g]
        if genres:
            video_tag.setGenres(genres)
    
    if 'country' in info_dict:
        countries = info_dict['country']
        if isinstance(countries, str):
            countries = [countries]
        elif isinstance(countries, list):
            countries = [str(c) for c in countries if c]
        if countries:
            video_tag.setCountries(countries)
    
    if 'director' in info_dict:
        directors = info_dict['director']
        if isinstance(directors, str):
            directors = [directors]
        elif isinstance(directors, list):
            directors = [str(d) for d in directors if d]
        if directors:
            video_tag.setDirectors(directors)
    
    if 'writer' in info_dict:
        writers = info_dict['writer']
        if isinstance(writers, str):
            writers = [writers]
        elif isinstance(writers, list):
            writers = [str(w) for w in writers if w]
        if writers:
            video_tag.setWriters(writers)
    
    if 'studio' in info_dict:
        studios = info_dict['studio']
        if isinstance(studios, str):
            studios = [studios]
        elif isinstance(studios, list):
            studios = [str(s) for s in studios if s]
        if studios:
            video_tag.setStudios(studios)
    
    if 'tag' in info_dict:
        tags = info_dict['tag']
        if isinstance(tags, str):
            tags = [tags]
        elif isinstance(tags, list):
            tags = [str(t) for t in tags if t]
        if tags:
            video_tag.setTags(tags)
    
    # Další informace
    if 'mpaa' in info_dict:
        video_tag.setMpaa(str(info_dict['mpaa']))
    if 'trailer' in info_dict:
        video_tag.setTrailer(str(info_dict['trailer']))
    if 'path' in info_dict:
        video_tag.setPath(str(info_dict['path']))
    if 'filenameandpath' in info_dict:
        video_tag.setFilenameAndPath(str(info_dict['filenameandpath']))
    if 'imdbnumber' in info_dict:
        video_tag.setIMDBNumber(str(info_dict['imdbnumber']))
    
    # Hudební video informace
    if 'artist' in info_dict:
        artists = info_dict['artist']
        if isinstance(artists, str):
            artists = [artists]
        elif isinstance(artists, list):
            artists = [str(a) for a in artists if a]
        if artists:
            video_tag.setArtists(artists)
    
    if 'album' in info_dict:
        video_tag.setAlbum(str(info_dict['album']))
    
    if 'track' in info_dict and info_dict['track']:
        try:
            video_tag.setTrackNumber(int(info_dict['track']))
        except (ValueError, TypeError):
            pass 