
# -*- coding: utf-8 -*-
"""
Series actions helpers: lokální akce pro označování pokroku v seriálech.
Oddělené od routeru pro lepší údržbu a přehled.
"""
import re
import os
from urllib.parse import unquote, urlparse
import json
import xbmc
import xbmcgui
import xbmcaddon
from resources.lib.utils.log_utils import get_logger
from resources.lib.series import series_manager  # top-level modul vedle sm3_entry.py
from resources.lib.series.series_helpers import now_iso_utc

log = get_logger()



ADDON_ID = 'plugin.video.mmirousek_v3'
ADDON = xbmcaddon.Addon(ADDON_ID)
ADDON_NAME = ADDON.getAddonInfo('name')


def _invalidate_series_filtered_cache():
    """Invaliduje cache sekcí Nově zařazené / Rozkoukané / Dosledované."""
    try:
        from resources.lib.cache.menu_cache_server import get_menu_cache_server

        cache_server = get_menu_cache_server()
        for key in (
            'series_filtered_menu_v1_new',
            'series_filtered_menu_v1_in_progress',
            'series_filtered_menu_v1_completed',
        ):
            cache_server.invalidate_menu(key)
    except Exception as ex:
        log.warning(f"[SeriesActions] Invalidate series filtered cache selhalo: {ex}")


def series_mark_episode(params, _addon=ADDON, _profile=None):
    """
    Označení jedné epizody (zhlédnuté / rozkoukané / reset).
    Očekává: series_name, season (int/str), episode (int/str), progress (float 0..100)
    """
    try:
        if _profile is None:
            _profile = xbmc.translatePath(_addon.getAddonInfo('profile'))
        sm = series_manager.SeriesManager(_addon, _profile)

        series_name = params.get('series_name')
        season = int(params.get('season'))
        episode = int(params.get('episode'))
        progress = float(params.get('progress'))

        sm.mark_episode_progress(series_name, season, episode, progress, set_by='manual')
        
        # Sync na SQL/Trakt má smysl jen při označení jako zhlédnuté.
        # U resetu/partial progress by přepsal ruční stav zpět na watched.
        if progress >= 90.0:
            try:
                sm.sync_series_with_sql(series_name=series_name)
            except Exception as ex:
                log.warning(f"[SeriesActions] Chyba pri cíleném sync_series_with_sql: {ex}")
        else:
            log.debug(
                f"[SeriesActions] Preskakuji sync_series_with_sql pro manual reset/partial progress ({progress}%), aby se stav neprepsal zpet."
            )

        _invalidate_series_filtered_cache()
            
        xbmcgui.Dialog().notification(ADDON_NAME, "Epizoda označena.", xbmcgui.NOTIFICATION_INFO, 2000)
        xbmc.executebuiltin('Container.Refresh()')
    except Exception as e:
        log.error(f'[SeriesActions] CHYBA series_mark_episode – {e}')
        xbmcgui.Dialog().notification(ADDON_NAME, "Chyba při označení epizody", xbmcgui.NOTIFICATION_ERROR, 3000)


def series_mark_season(params, _addon=ADDON, _profile=None):
    """
    Označení celé sezóny (bulk) – nastaví progress všem epizodám dané sezóny,
    přepočítá stav sezóny a uloží.
    Očekává: series_name (str), tmdb_id (str/int – volitelné), season (str/int), progress (float 0..100)
    """
    try:
        if _profile is None:
            _profile = xbmc.translatePath(_addon.getAddonInfo('profile'))
        sm = series_manager.SeriesManager(_addon, _profile)

        series_name = params.get('series_name')
        tmdb_id = params.get('tmdb_id')  # může být None
        season = str(params.get('season')).strip()
        progress = float(params.get('progress'))

        # Načti data podle TMDb ID (pokud existuje), jinak podle názvu
        data = None
        if tmdb_id:
            file_path = os.path.join(sm.series_db_path, f"tmdb_{tmdb_id}.json")
            if os.path.exists(file_path):
                with open(file_path, 'r', encoding='utf-8') as f:
                    data = json.load(f)
        if not data:
            data = sm.load_series_data(series_name)
        if not data:
            xbmcgui.Dialog().notification(ADDON_NAME, "Data seriálu nenalezena", xbmcgui.NOTIFICATION_ERROR, 3000)
            return

        if season not in data.get('seasons', {}):
            xbmcgui.Dialog().notification(ADDON_NAME, f"Sezóna {season} nenalezena", xbmcgui.NOTIFICATION_ERROR, 3000)
            return

        # Označ všechny epizody dané sezóny
        for ep_num in list(data['seasons'][season].keys()):
            ep = data['seasons'][season][ep_num]
            ep['progress'] = round(progress, 1)
            ep['watched'] = progress >= 90.0
            if ep['watched']:
                ep['play_count'] = ep.get('play_count', 0) + 1
                # ISO UTC — lokalizovaný System.Date formát byl neparsovatelný (web, fromisoformat)
                ep['last_watched_at'] = now_iso_utc()
            ep['set_by'] = 'manual'

        # Přepočítej stav sezóny a ulož
        sm.recalc_and_save_season_state(data, season)
        
        # Sync na SQL/Trakt má smysl jen při označení jako zhlédnuté.
        # U resetu/partial progress by přepsal ruční stav zpět na watched.
        if progress >= 90.0:
            try:
                sm.sync_series_with_sql(series_name=series_name)
            except Exception as ex:
                log.warning(f"[SeriesActions] Chyba pri cíleném sync_series_with_sql: {ex}")
        else:
            log.debug(
                f"[SeriesActions] Preskakuji sync_series_with_sql pro manual reset/partial progress ({progress}%), aby se stav neprepsal zpet."
            )

        _invalidate_series_filtered_cache()

        xbmcgui.Dialog().notification(
            ADDON_NAME,
            f"Sezóna {season} označena jako {'zhlédnutá' if progress >= 90 else 'resetována'}",
            xbmcgui.NOTIFICATION_INFO, 2500
        )

        # Refresh aktuálního zobrazení
        xbmc.executebuiltin('Container.Refresh')


    except Exception as e:
        log.error(f'[SeriesActions] CHYBA series_mark_season – {e}')
        xbmcgui.Dialog().notification(ADDON_NAME, "Chyba při označení sezóny", xbmcgui.NOTIFICATION_ERROR, 3000)


def csfd_lookup_enhanced(series_name: str,
                         tmdb_id: str = None,
                         media_type: str = 'movies',
                         max_comments: int = 5,
                         top_n: int = 12):
    """
    ČSFD lookup 2026 – Vylepšený hybridní scraper.
    Vytahuje obrázky, herce a základ z lokální DB / TMDb API (šetří HTTP dotazy)
    a dodatečný popis a recenze tahá "light" funkcí z ČSFD.
    """
    import os
    import xbmcaddon, xbmcgui, xbmcvfs
    import xbmc
    from resources.lib.utils.csfd_scraper import CSFDScraper
    from resources.lib.database.metadata_db import MetadataDB
    from resources.lib.tmdb.tmdb_module import TMDb

    ADDON = xbmcaddon.Addon('plugin.video.mmirousek_v3')
    PROFILE = xbmcvfs.translatePath(ADDON.getAddonInfo('profile'))
    CACHE_DIR = os.path.join(PROFILE, 'csfd_cache')

    mt = (media_type or 'movies').lower()
    use_tv_credits = mt in ('shows', 'show', 'tv', 'tvshow', 'series')
    tid = tmdb_id
    if tid is not None and str(tid).strip() == '':
        tid = None

    scraper = CSFDScraper(cache_dir=CACHE_DIR)

    # 1. Lokální data z metadata_db.py a TMDb API
    local_info = {}
    db = MetadataDB()
    if tid:
        try:
            local_data = db.get(int(tid))
            if local_data:
                if local_data.get('poster_path'):
                    p = local_data['poster_path']
                    local_info['poster'] = p if p.startswith('http') else f"https://image.tmdb.org/t/p/w500{p}"
                if local_data.get('backdrop_path'):
                    b = local_data['backdrop_path']
                    local_info['fanart'] = b if b.startswith('http') else f"https://image.tmdb.org/t/p/original{b}"
                local_info['title_orig'] = local_data.get('original_title') or local_data.get('original_name') or ''
                
                release = local_data.get('release_date') or local_data.get('first_air_date') or ''
                if release:
                    local_info['year'] = release[:4]

                # Mapování ratingů z metadata DB na klíče, které používá CSFDInfoWindow
                if local_data.get('vote_average'):
                    local_info['tmdb_rating'] = local_data.get('vote_average')
                if local_data.get('vote_count'):
                    local_info['tmdb_votes'] = local_data.get('vote_count')
                if local_data.get('imdb_rating'):
                    local_info['imdb_rating'] = local_data.get('imdb_rating')
                if local_data.get('imdb_votes'):
                    local_info['imdb_votes'] = local_data.get('imdb_votes')
                if local_data.get('rt_rating'):
                    local_info['rotten_rating'] = local_data.get('rt_rating')
                if local_data.get('metascore'):
                    local_info['metacritic'] = local_data.get('metascore')
                if local_data.get('box_office'):
                    local_info['box_office'] = local_data.get('box_office')
                
                genres = local_data.get('genres', [])
                if isinstance(genres, list):
                    local_info['genres'] = [g.get('name', '') for g in genres if isinstance(g, dict)]

                # Stažení herců přes TMDb API
                # language nedávat do URL – _call_api / _call_api_raw ho doplní přes params
                try:
                    tmdb_api = TMDb(ADDON.getSetting('tmdb_api_key') or "f7f51775877e0bb6703520952b3c7840")
                    credits_path = f"/tv/{tid}/credits" if use_tv_credits else f"/movie/{tid}/credits"
                    credits_response = tmdb_api._call_api(credits_path)
                    credits_data = credits_response.json()
                    
                    if credits_data and 'cast' in credits_data:
                        local_info['cast'] = []
                        for actor in credits_data['cast'][:30]:  # Prvních 30 herců
                            thumb = f"https://image.tmdb.org/t/p/w185{actor['profile_path']}" if actor.get('profile_path') else ""
                            local_info['cast'].append({
                                'name': actor.get('name', ''),
                                'thumb': thumb,
                                'id': actor.get('id'),
                            })
                except Exception as e:
                    import logging
                    logging.getLogger(__name__).warning(f"[CSFD_HYBRID] Nelze načíst TMDb herce: {e}")

        except Exception as e:
            import logging
            logging.getLogger(__name__).warning(f"[CSFD_HYBRID] Nelze načíst z lokální DB: {e}")
        finally:
            db.close()

    # 2. Vyhledání na ČSFD
    candidates = scraper.search(series_name, top_n=top_n)
    if not candidates:
        xbmcgui.Dialog().notification(
            "ČSFD",
            "Nic nenalezeno (CSFD může blokovat boty – zkus znovu)",
            xbmcgui.NOTIFICATION_WARNING,
            5000,
        )
        return

    # 3. Výběr uživatelem
    idx = xbmcgui.Dialog().select(f"ČSFD • {series_name}", [t for t, _ in candidates])
    if idx < 0: return

    chosen_title, chosen_url = candidates[idx]
    
    # 4. Získání textových detailů (Light scrape bez obrázků a herců!)
    xbmcgui.Dialog().notification("ČSFD", "Stahuji detaily a recenze...", xbmcgui.NOTIFICATION_INFO, 1500)
    info = scraper.get_light_detail(chosen_url, max_comments=max_comments)

    # Spojení lokálních a ČSFD dat (Lokální mají přednost v případě obrázků a herců)
    merged_info = info.copy()
    for k, v in local_info.items():
        if v: # Pokud jsme lokálně našli, přepíšeme ČSFD (platí zejména pro cast, poster, fanart)
            merged_info[k] = v

    # Fallback pro Kodi Fanart
    kodi_fanart = xbmc.getInfoLabel('ListItem.Art(fanart)') or xbmc.getInfoLabel('Container.Art(fanart)')
    
    # Zajištění formátu názvu
    if not merged_info.get("title_cz"):
        merged_info["title_cz"] = chosen_title.split('[')[0].strip()

    # 5. Zobrazení v novém krásném XML Skinu
    try:
        from resources.lib.ui.csfd_info_window import CSFDInfoWindow
        CSFDInfoWindow.show_info(merged_info, chosen_title=chosen_title.split('[')[0].strip(), kodi_fanart=kodi_fanart)
    except Exception as e:
        import logging
        logging.getLogger(__name__).error(f"[CSFD_HYBRID] Selhalo otevření CSFDInfoWindow: {e}")
        xbmcgui.Dialog().notification("Chyba", "Nepodařilo se načíst XML vzhled", xbmcgui.NOTIFICATION_ERROR)
