# wcs/search_series.py

import sys
import re
import difflib
import xml.etree.ElementTree as ET
from urllib.parse import quote_plus

import xbmcaddon
import xbmcplugin
import xbmcgui
import xbmc

# Importy našich modulů
from wcs.webshare import WebshareClient as webshare_api
from wcs.ui import UI as ui
from wcs import user_data, utils
from wcs.utils import extract_quality

# Konstanty přesunuté z router.py
CATEGORIES = ['', 'video', 'images', 'audio', 'archives', 'docs', 'adult']
SORTS = ['', 'recent', 'rating', 'largest', 'smallest']

# === SERIÁLOVĚ SPECIFICKÉ FUNKCE ===

# Hlavní funkce pro vyhledávání seriálů (WRAPPER)
def perform_search_and_display(addon, params, handle):
    """
    WRAPPER: Tenký wrapper pro centrální funkci search_and_select_series_file.
    Používá se z menu doplňku přes router.
    """
    # OPRAVA: Kontrola zda se nejedná o opětovné zobrazení po ukončení přehrávání
    movie_playing_from_search = addon.getSetting('movie_playing_from_search')
    if movie_playing_from_search == 'true':
        addon.setSetting('movie_playing_from_search', 'false')
        xbmc.log("[plugin.video.milionar] perform_search_and_display: Series playback ended, preventing re-search", level=xbmc.LOGINFO)
        xbmcplugin.endOfDirectory(handle)
        return

    # Získání hledaného výrazu
    what = params.get('what')
    if not what:
        what = ui.ask('', addon)
        if not what:
            xbmcplugin.endOfDirectory(handle)
            return

    # Extrakce S/E informací z dotazu  
    s_e = utils.extract_season_episode(what)
    season, episode = s_e if s_e != (None, None) else (None, None)
    
    # Extrakce názvu seriálu z dotazu (OPRAVA: odstraníme S/E část)
    series_name = what
    if season is not None and episode is not None:
        # Odstraníme S/E část z názvu seriálu
        series_name = re.sub(r'\s+S\d+E\d+.*', '', what, flags=re.IGNORECASE).strip()
        # Pokud zbyl jen prázdný string, použijeme celý dotaz
        if not series_name:
            series_name = what
    
    # Volání centrální funkce
    selected_file = search_and_select_series_file(
        search_query=what,
        series_name=series_name,
        season=season,
        episode=episode,
        plot=params.get('tmdb_plot', ''),
        poster=params.get('tmdb_thumb', ''),
        fanart=params.get('tmdb_fanart', ''),
        rating=params.get('tmdb_rating', ''),
        genre=params.get('tmdb_genre', ''),
        director=params.get('tmdb_director', ''),
        runtime=params.get('tmdb_runtime', ''),
        addon=addon,
        tmdb_id=params.get('tmdb_id'),
        from_library=False
    )
    
    # Pokud byl vybrán soubor, přehraj ho
    if selected_file and 'ident' in selected_file and 'name' in selected_file:
        ident = selected_file['ident']
        name = selected_file['name']
        
        params_dict = {
            'tmdb_title': params.get('tmdb_title', what),
            'tmdb_plot': params.get('tmdb_plot', ''),
            'tmdb_thumb': params.get('tmdb_thumb', ''),
            'tmdb_fanart': params.get('tmdb_fanart', ''),
            'tmdb_rating': params.get('tmdb_rating', ''),
            'tmdb_genre': params.get('tmdb_genre', ''),
            'tmdb_director': params.get('tmdb_director', ''),
            'tmdb_runtime': params.get('tmdb_runtime', '')
        }
        
        webshare_api.resolve_playable_item(ident, name, addon, params_dict, handle)
        return
    
    # Ukončení seznamu v Kodi
    xbmcplugin.endOfDirectory(handle) 

# Funkce pro specifické hledání seriálů z TMDb kontextu (WRAPPER)
def search_and_handle_episode(params, addon, handle):
    """
    WRAPPER: Tenký wrapper pro centrální funkci search_and_select_series_file.
    Používá se z TMDb/knihovny pro specifické epizody.
    """
    series_name = params['series_name']
    season = int(params['season'])
    episode = int(params['episode'])
    ep_name = params.get('ep_name', '')

    search_str = f"{series_name} S{season:02d}E{episode:02d}"
    
    # Kontrola přihlášení - pokud není přihlášen, zobrazí dialog a skončí
    ws_user = addon.getSetting('wsuser')
    ws_pass = addon.getSetting('wspass')
    
    if not ws_user or not ws_pass:
        user_data._check_credentials_and_prompt(addon)
        return
    
    # Vlastní logika vyhledání a přehrání
    selected_file = _internal_search_and_select_series_file(
        search_query=search_str,
        series_name=series_name,
        season=season,
        episode=episode,
        ep_name=ep_name,
        plot=params.get('tmdb_plot', ''),
        poster=params.get('tmdb_thumb', ''),  # poster seriálu pro UI
        fanart=params.get('tmdb_fanart', ''),
        rating=params.get('tmdb_rating', ''),
        genre=params.get('tmdb_genre', ''),
        year=params.get('tmdb_year', ''),
        runtime=params.get('tmdb_runtime', ''),
        addon=addon,
        tmdb_id=params.get('tmdb_id'),
        episode_thumb=params.get('tmdb_episode_thumb', '')  # still epizody pro úvodní dialog
    )
    
    if selected_file and 'ident' in selected_file:
        ident = selected_file['ident']
        name = selected_file['name']
        
        # Sestavíme správný název ve formátu "Název seriálu – Název epizody"
        if ep_name and ep_name != f"Epizoda {episode}":
            display_title = f"{series_name} – {ep_name}"
        else:
            display_title = f"{series_name} S{season:02d}E{episode:02d}"
            
        params_dict = {
            'tmdb_title': display_title,
            'tmdb_plot': params.get('tmdb_plot', ''),
            'tmdb_thumb': params.get('tmdb_thumb', ''),
            'tmdb_season': season,
            'tmdb_episode': episode,
            'tmdb_series_name': series_name
        }
        
        xbmc.log(f"[plugin.video.milionar] search_and_handle_episode: Resolving playable item: {name}", level=xbmc.LOGINFO)
        
        # Uložit do historie naposledy přehraných
        try:
             item_data = {
                 'title': series_name, 
                 'episode_title': ep_name or f"S{season:02d}E{episode:02d}", 
                 'year': params.get('tmdb_year', ''),
                 'poster': params.get('tmdb_thumb', ''),
                 'rating': params.get('tmdb_rating', ''),
                 'media_type': 'series',
                 'tmdb_id': params.get('tmdb_id'),
                 'season': season,
                 'episode': episode,
                 'plot': params.get('tmdb_plot', ''),
                 'genre': params.get('tmdb_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 in search_and_handle_episode: {e}", level=xbmc.LOGERROR)

        webshare_api.resolve_playable_item(ident, name, addon, params_dict, handle)
        return

# === CENTRÁLNÍ FUNKCE PRO VYHLEDÁVÁNÍ A VÝBĚR SERIÁLŮ ===

def _internal_search_and_select_series_file(search_query, series_name='', season=None, episode=None, ep_name='', plot='', poster='', fanart='', rating='', genre='', director='', runtime='', year='', addon=None, tmdb_id=None, from_library=False, autoplay_request=False, episode_thumb=''):
    """
    INTERNÍ funkce pro vyhledávání seriálů - bez callback logiky.
    Předpokládá, že uživatel je již přihlášen.
    """
    if not addon:
        addon = xbmcaddon.Addon()

    try:
        token = webshare_api.revalidate(addon, lambda msg, heading, **kwargs: ui.popinfo(msg, heading, **kwargs))
        if not token:
            return None

        queries = [search_query]
        if season is not None and episode is not None:
            if series_name:
                queries.extend([
                    f"{series_name} S{season:02d}E{episode:02d}",
                    f"{series_name} {season}x{episode:02d}",
                ])
        queries = list(dict.fromkeys(queries))

        all_files = {}
        limit = 25
        
        for query in queries:
            response = webshare_api.api_call('search', {
                'what': query,
                'wst': token,
                'category': 'video',
                'limit': limit,
                'offset': 0
            })
            xml = ET.fromstring(response.content)
            if webshare_api.is_ok(xml):
                for file in xml.iter('file'):
                    ident = file.findtext('ident')
                    if ident and ident not in all_files:
                        all_files[ident] = {e.tag: e.text for e in file}
        
        files = list(all_files.values())
        
        if not files:
            ui.popinfo(f"Nebyly nalezeny žádné soubory pro '{search_query}'", addon.getAddonInfo('name'))
            return None
        
        files = sort_series_files_by_priority(files, search_query)
        
        from wcs.utils import is_valid_file_size
        filtered_files = []
        for item in files:
            filename = item.get('name', '')
            quality = extract_quality(filename)
            
            if is_valid_file_size(quality, item.get('size')):
                filtered_files.append(item)
            else:
                xbmc.log(f"[plugin.video.milionar] Autoplay: Skipping file due to size validation: '{filename}'", level=xbmc.LOGINFO)
        
        files = filtered_files
        
        if autoplay_request:
            autoplay_enabled_global = addon.getSettingBool('autoplay_enabled_global')
            if autoplay_enabled_global:
                xbmc.log(f"[plugin.video.milionar] Autoplay request: Selecting first file automatically", level=xbmc.LOGINFO)
                return files[0] if files else None
            else:
                xbmc.log(f"[plugin.video.milionar] Autoplay request: Autoplay disabled globally, not playing next episode", level=xbmc.LOGINFO)
                return None
        
        from wcs.ui.dialogs.DialogWcsSearch import show_search_dialog
        
        # Sestavíme správný název ve formátu "Název seriálu – Název epizody"
        if season and episode and ep_name and ep_name != f"Epizoda {episode}":
            movie_title = f"{series_name} – {ep_name}"
        elif season and episode:
            movie_title = f"{series_name} S{season:02d}E{episode:02d}"
        else:
            movie_title = series_name or search_query
            
        selected_file = show_search_dialog(
            search_query=search_query,
            movie_title=movie_title,
            movie_year=year,
            poster_url=poster,
            fanart_url=fanart,
            rating=rating,
            genre=genre,
            director=director,
            runtime=runtime,
            plot=plot,
            search_results=files,
            is_episode=True,
            series_name=series_name or search_query.split()[0] if search_query else '',
            season_number=season,
            episode_number=episode,
            episode_title=ep_name,
            tmdb_id=tmdb_id,
            episode_thumb=episode_thumb
        )
        
        return selected_file
        
    except Exception as e:
        ui.popinfo(f"Chyba při vyhledávání: {e}", addon.getAddonInfo('name'))
        return None

def search_and_select_series_file(search_query, series_name='', season=None, episode=None, ep_name='', plot='', poster='', fanart='', rating='', genre='', director='', runtime='', addon=None, tmdb_id=None, from_library=False, autoplay_request=False):
    """
    CENTRÁLNÍ funkce pro vyhledávání a výběr souboru seriálu.
    Používá se ze všech míst - menu doplňku, knihovny, TMDb.
    
    Args:
        search_query (str): Dotaz pro vyhledávání na Webshare
        series_name (str): Název seriálu
        season (int): Číslo sezóny
        episode (int): Číslo epizody
        ep_name (str): Název epizody
        plot (str): Popis
        poster (str): URL obrázku
        fanart (str): URL fanart
        rating (str): Hodnocení
        genre (str): Žánr
        director (str): Režisér
        runtime (str): Délka
        addon: Instance addonu
        tmdb_id (int): TMDb ID
        from_library (bool): Volá se z knihovny Kodi
        autoplay_request (bool): Zda se jedná o autoplay požadavek
        
    Returns:
        dict or None: Vybraný soubor nebo None
    """
    if not addon:
        addon = xbmcaddon.Addon()

    # Kontrola přihlášení - pokud není přihlášen, zobrazí dialog a skončí
    ws_user = addon.getSetting('wsuser')
    ws_pass = addon.getSetting('wspass')
    
    if not ws_user or not ws_pass:
        user_data._check_credentials_and_prompt(addon)
        return None

    return _internal_search_and_select_series_file(
        search_query, series_name, season, episode, ep_name, plot, poster, fanart, rating, genre, director, runtime, addon, tmdb_id, from_library, autoplay_request
    )

# === FUNKCE PRO ŘAZENÍ SERIÁLŮ ===

def sort_series_files_by_priority(files, query):
    """
    Seřadí soubory seriálů podle pokročilého skórování s prioritami pro SD soubory.
    
    Args:
        files (list): Seznam Webshare souborů
        query (str): Vyhledávací dotaz
        
    Returns:
        list: Seřazené soubory (nejlepší první)
    """
    # Extrakce season/episode informací z dotazu
    s_e = utils.extract_season_episode(query)
    
    def _score_search_item_wrapper(item):
        """Wrapper pro _score_search_item funkci."""
        filename = item.get('name', '')
        detected_quality = extract_quality(filename)
        
        # Pokud soubor nemá detekovanou kvalitu (je SD), použijeme speciální řazení
        if detected_quality == 'SD':
            return _score_no_quality_item_standalone(item, query, s_e)
        
        # Pro soubory s detekovanou kvalitou používáme standardní algoritmus
        return _score_search_item_standalone(item, query, s_e)
    
    # Seřazení podle skóre (sestupně)
    files.sort(key=_score_search_item_wrapper, reverse=True)
    return files

def _score_search_item_standalone(item, original_query, season_episode_tuple):
    """
    Pokročilé skórování pro seriály kombinující kvalitu s logikou pro epizody.
    Používá se pro soubory s detekovanou kvalitou.
    """
    # Použijeme základní skórování pro soubory s kvalitou + epizodové bonusy
    from wcs.utils import calculate_advanced_score
    base_advanced_score = calculate_advanced_score(item, original_query)
    
    # KRITICKÝ BONUS: Soubory s detekovanou kvalitou mají VŽDY vyšší prioritu než SD
    # Přidáme 20000 bodů pro jakoukoliv detekovanou kvalitu, aby byly nad SD soubory
    quality_detected_bonus = 20000
    
    # Přidáme bonusy specifické pro seriály
    filename = item.get('name', '')  # OPRAVA: Definovat filename
    name = filename.lower()
    episode_bonus = 0
    
    # BONUS ZA PŘESNOU SHODU S/E FORMÁTU (+2000 bodů)
    if season_episode_tuple != (None, None):
        s_e_item = utils.extract_season_episode(name)
        if s_e_item == season_episode_tuple:
            episode_bonus += 2000
            
    # BONUS ZA NÁZEV EPIZODY (+500 bodů) 
    if season_episode_tuple != (None, None):
        parts = original_query.split()
        if len(parts) > 2:
            ep_name_query = ' '.join(parts[2:]).lower()
            if ep_name_query and ep_name_query in name:
                episode_bonus += 500
    
    # Kombinované skóre: KVALITA VŽDY PRVNÍ + pokročilé + epizodové bonusy
    final_score = quality_detected_bonus + base_advanced_score + episode_bonus
    
    # OPRAVA: Přidat unikátní identifikátor pro rozlišení duplikátů
    # Použijeme hash názvu souboru jako desetinnou část skóre
    import hashlib
    filename_hash = int(hashlib.md5(filename.encode()).hexdigest()[:8], 16)
    unique_score = filename_hash / 100000000.0  # Desetinná část 0-1
    
    return final_score + unique_score

def _score_no_quality_item_standalone(item, original_query, season_episode_tuple):
    """
    Speciální skórování pro soubory bez detekované kvality v názvu.
    Priorita: 1. MKV formát, 2. česká řeč, 3. velikost souboru.
    """
    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: MKV FORMÁT (0-10000 bodů) ===
    format_score = 0
    if name.endswith('.mkv'):
        format_score = 10000  # MKV soubory mají nejvyšší prioritu
    else:
        format_score = 0      # Ostatní formáty
    
    # === 2. PRIORITA: ČESKÁ ŘEČ (0-5000 bodů) ===
    cz_score = 0
    if re.search(r'cz.*dabing|czech.*dub', name):
        cz_score = 5000  # CZ dabing = nejvyšší
    elif 'multidub' in name:
        cz_score = 4000  # MultiDub
    elif 'czen' in name or 'cz-eng' in name:
        cz_score = 3500  # CZ+EN
    elif re.search(r'\bcz\b|\.cz\.|\.cz$', name):
        cz_score = 3000  # Obecné CZ (včetně .cz. a .cz na konci)
    elif 'slovak' in name or re.search(r'\bsk\b', name):
        cz_score = 2000  # SK
    else:
        cz_score = 0     # Ostatní jazyky včetně N/A - NEJNIŽŠÍ PRIORITA
    
    # === 3. PRIORITA: VELIKOST SOUBORU (0-1000 bodů) ===
    size_score = 0
    try:
        size_bytes = int(item.get('size', 0))
        if size_bytes > 0:
            # Logaritmické škálování velikosti (větší = lepší)
            if size_bytes >= 50 * 1024**3:    # 50GB+
                size_score = 1000
            elif size_bytes >= 30 * 1024**3:  # 30GB+
                size_score = 800
            elif size_bytes >= 15 * 1024**3:  # 15GB+
                size_score = 600
            elif size_bytes >= 8 * 1024**3:   # 8GB+
                size_score = 400
            elif size_bytes >= 3 * 1024**3:   # 3GB+
                size_score = 200
            else:                              # < 3GB
                size_score = 100
    except (ValueError, TypeError):
        size_score = 0
    
    # === BONUSY SPECIFICKÉ PRO SERIÁLY ===
    episode_bonus = 0
    
    # BONUS ZA PŘESNOU SHODU S/E FORMÁTU (+2000 bodů)
    if season_episode_tuple != (None, None):
        s_e_item = utils.extract_season_episode(name)
        if s_e_item == season_episode_tuple:
            episode_bonus += 2000
            
    # BONUS ZA NÁZEV EPIZODY (+500 bodů) 
    if season_episode_tuple != (None, None):
        parts = original_query.split()
        if len(parts) > 2:
            ep_name_query = ' '.join(parts[2:]).lower()
            if ep_name_query and ep_name_query in name:
                episode_bonus += 500
    
    # === FINÁLNÍ SKÓRE ===
    # Priorita: MKV (10000) > CZ řeč (5000) > velikost (1000) > základní shoda (1000) + epizodové bonusy (2500)
    final_score = base_score + format_score + cz_score + size_score + episode_bonus
    
    # OPRAVA: Přidat unikátní identifikátor pro rozlišení duplikátů
    # Použijeme hash názvu souboru jako desetinnou část skóre
    import hashlib
    filename_hash = int(hashlib.md5(filename.encode()).hexdigest()[:8], 16)
    unique_score = filename_hash / 100000000.0  # Desetinná část 0-1
    
    return final_score + unique_score 