# -*- coding: utf-8 -*-
import sys
import json
import urllib.parse as urlparse
from urllib.parse import urlencode
import os  # kvůli cestám na artwork

import xbmc
import xbmcgui
import xbmcplugin
import xbmcaddon
import xbmcvfs
# přidej k importům nahoře
from resources.lib.utils.ui_utils import add_menu_item as ui_add_item, pick_icon as ui_pick_icon
from resources.lib.utils.log_utils import get_logger
from resources.lib.utils.context_builder import style_context_menu
from resources.lib.tmdb.tmdb_kodi import set_video_info

log = get_logger()
ICON_DIR = 'csfd'  # podsložka pro ikonky ČSFD

# Knihovna doplňku (parsování, fetch/cache, util)
# Pozn.: diff_by_id importujeme uvnitř funkcí až při použití.
from resources.lib.csfd_toplist.scraper import (
    get_items,               # ponecháno pro případné další využití
    prepare_all_with_progress,  # kompletní příprava s progress barem
    clean_cache,             # mazání cache (toplist HTML a/nebo detaily)
    cache_stats              # NOVÉ: statistika cache (bytes + počty + cesty)
)

ADDON = xbmcaddon.Addon()
ADDON_ID = ADDON.getAddonInfo('id')
HANDLE = int(sys.argv[1])
BASE_URL = sys.argv[0]

JSON_FILMY = 'csfd_filmy.json'
JSON_SERIALY = 'csfd_serialy.json'

# TMDb obrázky (použijeme, když je v JSON 'poster_path')
TMDB_IMG_BASE = "https://image.tmdb.org/t/p/w500"


# -------------------------------- util ----------------------------------------
# --- POČÍTACÍ UTILITy PRO HLAVNÍ MENU ČSFD TOPLISTU --------------------------

def _safe_read_json(path: str):
    """Bezpečně načte JSON přes xbmcvfs.File, vrátí Python objekt nebo []."""
    try:
        if not xbmcvfs.exists(path):
            return []
        f = xbmcvfs.File(path, 'r')
        raw = f.read()
        f.close()
        if isinstance(raw, bytes):
            raw = raw.decode('utf-8', 'ignore')
        return json.loads(raw or '[]')
    except Exception:
        return []

def _profile_root():
    p = xbmcvfs.translatePath(ADDON.getAddonInfo('profile'))
    if not p.endswith(('/', '\\')):
        p += '/'
    xbmcvfs.mkdirs(p)
    return p

def _count_toplist(category: str) -> int:
    """
    Vrátí počet položek v JSONu csfd_filmy.json / csfd_serialy.json
    category: 'films' | 'series'
    """
    prof = _profile_root()
    fname = 'csfd_filmy.json' if category == 'films' else 'csfd_serialy.json'
    data = _safe_read_json(prof + fname)
    return int(len(data or []))

def _count_extra_playlist_movies() -> int:
    """
    Vrátí počet filmů z playlistu, které nejsou v Toplistu (mimo Top 300):
    - načte playlist_index.json
    - načte csfd_filmy.json a udělá diff podle tmdb_id
    """
    try:
        from resources.lib.database.metadata_db import db
        items = db.get_all_playlist_items()
    except Exception:
        items = []
    if not items:
        return 0

    # toplist film IDs
    prof = _profile_root()
    toplist = _safe_read_json(prof + 'csfd_filmy.json')
    toplist_ids = {int(x.get('tmdb_id') or 0) for x in (toplist or []) if int(x.get('tmdb_id') or 0) > 0}

    # extra = vše z playlistu typu movie, které nemá tmdb_id v toplist_ids (nebo tmdb_id==0)
    extra = 0
    for it in items:
        if (it.get('media_type') or '').lower() != 'movie':
            continue
        tid = int(it.get('tmdb_id') or 0)
        if tid == 0 or tid not in toplist_ids:
            extra += 1
    return extra

def _lime(n: int) -> str:
    """Vrátí počet zabalený do [COLOR lime]...[/COLOR] pro pěkný label."""
    return f"[COLOR lime]{n}[/COLOR]"

def build_url(query):
    return BASE_URL + '?' + urlencode(query, encoding='utf-8')

MAIN_PLUGIN_URL = f"plugin://{ADDON_ID}/"

def _main_router_url(**kwargs) -> str:
    """
    URL do hlavního routeru doplňku (ne do csfd_toplist adaptéru).
    Používá se pro context menu akce jako csfd_lookup_enhanced.
    """
    return MAIN_PLUGIN_URL + '?' + urlencode(kwargs, encoding='utf-8')

def translate_profile_path(*parts) -> str:
    """
    Cesta do profilové složky doplňku.
    """
    root = xbmcvfs.translatePath(ADDON.getAddonInfo('profile'))
    if not root.endswith(('/', '\\')):
        root += '/'
    xbmcvfs.mkdirs(root)
    return root + '/'.join(parts)

def json_path_for(category: str) -> str:
    return translate_profile_path(JSON_FILMY if category == 'films' else JSON_SERIALY)

def save_json(category: str, items: list):
    """
    Uloží JSON (csfd_filmy.json / csfd_serialy.json) do profilové složky.
    """
    p = json_path_for(category)
    f = xbmcvfs.File(p, 'w')
    try:
        data = json.dumps(items, ensure_ascii=False, indent=2)
        f.write(bytearray(data, 'utf-8'))
    finally:
        f.close()
    xbmcgui.Dialog().notification("ČSFD Toplist", f"Uloženo: {p}", xbmcgui.NOTIFICATION_INFO, 3000)

def load_json(category: str) -> list:
    """
    Načte JSON z profilové složky. Vyhodí FileNotFoundError, pokud neexistuje.
    """
    p = json_path_for(category)
    if not xbmcvfs.exists(p):
        raise FileNotFoundError(f"Chybí JSON: {p}")
    f = xbmcvfs.File(p, 'r')
    try:
        raw = f.read()
    finally:
        f.close()
    if isinstance(raw, bytes):
        raw = raw.decode('utf-8', 'ignore')
    return json.loads(raw)


def render_items(items: list, is_tv: bool):
    """
    Vyrenderuje položky do seznamu (ListItem).
    Kliknutí posíláme do hlavního routeru (action='csfd_play_or_open').
    """
    m3u_tmdb = set()
    m3u_keys = set()
    if not is_tv:
        try:
            from resources.lib.database.metadata_db import db
            pl_items = db.get_all_playlist_items()
            for pit in pl_items:
                if (pit.get('media_type') or '').lower() == 'movie':
                    tid = int(pit.get('tmdb_id') or 0)
                    if tid > 0:
                        m3u_tmdb.add(tid)
                    tnorm = (pit.get('title_norm') or '').strip()
                    y = int(pit.get('year') or 0) if pit.get('year') else None
                    m3u_keys.add((tnorm, y))
                    m3u_keys.add((tnorm, None))
        except Exception:
            pass

    for it in items:
        rank = it.get('rank')
        title = it.get('title') or '???'
        year = it.get('year')
        rating_percent = it.get('rating_percent')
        label = f"{rank}. {title}" if rank else title
        if year:
            label += f" ({year})"
        if isinstance(rating_percent, (int, float)):
            label += f" — {rating_percent:.1f}%"

        # Zobrazení stvrzení existence v M3U (Zelený odznak)
        if not is_tv:
            is_matched = False
            tid = int(it.get('tmdb_id') or 0)
            if tid > 0 and tid in m3u_tmdb:
                is_matched = True
            else:
                try:
                    tnorm = _normalize_title(it.get('title') or it.get('originaltitle') or '')
                    y_val = int(it.get('year') or 0) if it.get('year') else None
                    if (tnorm, y_val) in m3u_keys or (tnorm, None) in m3u_keys:
                        is_matched = True
                except NameError:
                    pass # safety check pro import re-order

            if is_matched:
                label += " [COLOR lime][B]M3U[/B][/COLOR]"

        li = xbmcgui.ListItem(label=label)

        # Info (CZ plot z TMDb, pokud je)
        info_labels = {
            'title': it.get('title') or title,
            'originaltitle': title,
            'year': year or 0,
            'genre': ' / '.join(it.get('genres') or []),
            'country': ' / '.join(it.get('countries') or []),
            'duration': it.get('runtime_min') or 0,
            'rating': (float(rating_percent) / 10.0) if rating_percent is not None else 0.0,
            'votes': str(it.get('votes') or ''),
            'mediatype': 'tvshow' if is_tv else 'movie',
            'plot': it.get('plot') or ''
        }

        # Label2 s TMDb ratingem (pokud je)
        if it.get('vote_avg') is not None and it.get('vote_count') is not None:
            li.setLabel2(f"TMDb {it['vote_avg']:.1f}/10 • {it['vote_count']} hlasů")
        set_video_info(li, info_labels)

        # Artwork (preferuj TMDb poster)
        art = {'icon': 'DefaultVideo.png'}
        poster_path = it.get('poster_path')
        if poster_path:
            poster_url = TMDB_IMG_BASE + poster_path
            art.update({'thumb': poster_url, 'icon': poster_url, 'poster': poster_url})
        li.setArt(art)

        # Context menu: ČSFD detail (rozšířený) — sjednoceno s TMDb/Trakt huby
        title_for_csfd = it.get('title') or title
        tmdb_id_for_csfd = str(it.get('tmdb_id') or '')
        media_type_for_csfd = 'shows' if is_tv else 'movies'
        csfd_url = _main_router_url(
            action='csfd_lookup_enhanced',
            series_name=title_for_csfd,
            tmdb_id=tmdb_id_for_csfd,
            media_type=media_type_for_csfd,
        )
        li.addContextMenuItems(style_context_menu([
            ("ČSFD detail (rozšířený)", f"RunPlugin({csfd_url})"),
        ]))

        # Cílové URL do hlavního routeru (přes adaptér se z toho stane action='csfd_play_or_open')
        params = {
            'action': 'play_or_open',
            'media_type': 'tv' if is_tv else 'movie',
            'title': it.get('title') or title
        }
        if not is_tv and (it.get('year') or None):
            params['year'] = it['year']
        # pokud máme tmdb_id z obohacení, pošli ho (primární klíč pro párování)
        if not is_tv and (it.get('tmdb_id') or 0):
            params['tmdb_id'] = it['tmdb_id']

        url = build_url(params)
        xbmcplugin.addDirectoryItem(handle=HANDLE, url=url, listitem=li, isFolder=False)

    xbmcplugin.endOfDirectory(HANDLE)

# ------------- helper pro artwork/menu + formátování --------------------------
def _addon_path(*parts) -> str:
    """
    Bezpečně složí absolutní cestu v rámci addonu pro artwork soubory.
    """
    base = ADDON.getAddonInfo('path')
    return os.path.join(base, *parts).replace('\\', '/')

def add_menu_item(label: str,
                  params: dict,
                  is_folder: bool = True,
                  icon: str = None,
                  thumb: str = None,
                  fanart: str = None,
                  description: str = None) -> None:
    """
    Vytvoří položku menu s volitelnými ikonami/obrázky a popisem.
    Pokud nejsou specifikovány, použijí se výchozí assety doplňku.
    """
    li = xbmcgui.ListItem(label=label)

    # Výchozí artwork – použij tvoje ČSFD logo, ulož na: resources/media/logo.png
    default_icon = _addon_path('resources', 'media', 'logo.png')
    default_thumb = default_icon

    # Fanart je volitelný; pokud soubor neexistuje, nepředáváme jej
    default_fanart = _addon_path('resources', 'media', 'fanart.jpg')
    if not xbmcvfs.exists(default_fanart):
        default_fanart = None

    art = {
        'icon': icon or default_icon,
        'thumb': thumb or default_thumb,
    }
    if fanart or default_fanart:
        art['fanart'] = fanart or default_fanart
    li.setArt(art)

    if description:
        # krátký popis (skin závisí, ale obvykle se zobrazí v detailu)
        tag = li.getVideoInfoTag()
        tag.setPlot(description)

    xbmcplugin.addDirectoryItem(HANDLE, build_url(params), li, is_folder)

def format_bytes(n: int) -> str:
    """
    Hezké formátování velikosti (B, KB, MB, GB).
    """
    try:
        n = int(n or 0)
    except Exception:
        n = 0
    units = ['B','KB','MB','GB','TB']
    i = 0
    f = float(n)
    while f >= 1024 and i < len(units)-1:
        f /= 1024.0
        i += 1
    if i == 0:
        return f"{int(f)} {units[i]}"
    return f"{f:.1f} {units[i]}"

# --- NORMALIZACE NÁZVŮ (stejně jako v playlist_index.py) ---------------------
import re
try:
    import unidecode
    def _strip_diacritics(s): return unidecode.unidecode(s or '')
except Exception:
    def _strip_diacritics(s): return s or ''

_PARENS_RE    = re.compile(r'[\(\[\{].*?[\)\]\}]')
_NON_ALNUM_RE = re.compile(r'[^a-z0-9]+')

def _normalize_title(s: str) -> str:
    s = _strip_diacritics((s or '').casefold())
    s = _PARENS_RE.sub(' ', s)
    s = _NON_ALNUM_RE.sub(' ', s)
    return ' '.join(s.split()).strip()

# --- ČTENÍ JSONŮ (ponech/už máš) ---------------------------------------------
# _safe_read_json(), _profile_root(), _lime() – jak jsme přidali dříve

# --- MATCH „FILMY v Toplistu“ × „Položky v playlist_index.json“ --------------
def _count_films_with_playlist_match() -> (int, int):
    """
    Vrátí (total_top_films, matched_in_playlist)
    - total_top_films: počet v csfd_filmy.json
    - matched_in_playlist: kolik z nich má stream v playlist_index.json
      (primárně match přes tmdb_id; fallback přes title_norm+year)
    """
    # načti toplist filmy
    prof = _profile_root()
    films = _safe_read_json(prof + 'csfd_filmy.json')  # list dictů
    total = int(len(films or []))
    if total == 0:
        return 0, 0

    # načti playlist index z databáze
    try:
        from resources.lib.database.metadata_db import db
        items = db.get_all_playlist_items()
    except Exception:
        items = []
    if not items:
        return total, 0

    # postav mapy pro rychlý lookup
    by_tmdb = {}
    by_title_year = {}
    for it in items:
        # jen filmy
        if (it.get('media_type') or '').lower() != 'movie':
            continue
        # tmdb mapa
        tid = int(it.get('tmdb_id') or 0)
        if tid > 0:
            by_tmdb[tid] = it
        # title_norm + year mapa
        tnorm = (it.get('title_norm') or '').strip()
        y = int(it.get('year') or 0) if it.get('year') else None
        key = (tnorm, y)
        by_title_year.setdefault(key, []).append(it)

    matched = 0
    for f in films:
        # 1) tmdb_id match
        tid = int(f.get('tmdb_id') or 0)
        if tid > 0 and tid in by_tmdb:
            matched += 1
            continue
        # 2) fallback: title_norm + year
        title = f.get('title') or f.get('originaltitle') or ''
        year  = int(f.get('year') or 0) if f.get('year') else None
        tnorm = _normalize_title(title)
        key   = (tnorm, year)
        if key in by_title_year and by_title_year[key]:
            matched += 1
            continue
        # navíc zkus bez roku
        key_no_year = (tnorm, None)
        if key_no_year in by_title_year and by_title_year[key_no_year]:
            matched += 1

    return total, matched


# -------------------------------- menu ----------------------------------------
def root_menu():
    """
    Hlavní menu ČSFD Toplistu — s počty:
    - Prohlížení filmů [CELKEM / S M3U]
    - Prohlížení seriálů [CELKEM]
    - Další filmy z playlistu [N_extra]
    - Příprava dat
    + Info řádek (neklikatelný)
    """

    # === DOPLŇ: pro sjednocené ikony (jen jednou nahoře v souboru) ===
    # from resources.lib.utils.ui_utils import add_menu_item as ui_add_item, pick_icon as ui_pick_icon
    # ICON_DIR = 'csfd'

    # --- dopočty (zachovávají se try/except z původního kódu) ---
    try:
        total_films, matched_films = _count_films_with_playlist_match()  # CELKEM / kolik má M3U
    except Exception:
        total_films, matched_films = 0, 0

    try:
        cnt_series = _count_toplist('series')
    except Exception:
        cnt_series = 0

    try:
        cnt_extra = _count_extra_playlist_movies()
    except Exception:
        cnt_extra = 0

    films_label_count = f"{_lime(total_films)} / {_lime(matched_films)}"

    # --- hlavní položky menu přes sdílené UI helpery ---
    # 1) Prohlížení filmů
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label=f"Prohlížení filmů {films_label_count}",
        plot=("Zobrazit a procházet TOP filmy podle ČSFD. "
              "Počet vpravo udává CELKEM / počet s M3U streamem."),
        action='browse_menu',
        art_icon=ui_pick_icon(ADDON, 'csfd_films.png', 'DefaultMovies.png', ICON_DIR),
        is_folder=True,
        category='films'
    )

    # 2) Prohlížení seriálů
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label=f"Prohlížení seriálů {_lime(cnt_series)}",
        plot="Zobrazit a procházet TOP seriály podle ČSFD.",
        action='browse_menu',
        art_icon=ui_pick_icon(ADDON, 'csfd_series.png', 'DefaultTVShows.png', ICON_DIR),
        is_folder=True,
        category='series'
    )

    # 3) Další filmy z playlistu
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label=f"Další filmy z playlistu {_lime(cnt_extra)}",
        plot=("Zobrazí filmy nalezené v M3U playlistu, které se nepodařilo spárovat s Top 300 "
              "podle ČSFD. Vyžaduje mít vytvořený M3U index (Příprava dat → Indexovat M3U → JSON)."),
        action='extra_playlist',  # adaptér na hlavní router: csfd_extra_playlist
        art_icon=ui_pick_icon(ADDON, 'csfd_extra.png', 'DefaultPlaylist.png', ICON_DIR),
        is_folder=True
    )

    # 4) Příprava dat
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label="Příprava dat",
        plot="Stáhnout/obnovit toplisty a detaily, správa cache.",
        action='prepare_menu',
        art_icon=ui_pick_icon(ADDON, 'csfd_prepare.png', 'DefaultFolder.png', ICON_DIR),
        is_folder=True
    )

    # --- INFO řádek (neklikatelný) ---
    info_text = (
        "[B]Legenda počtů:[/B][CR]"
        "• Filmy = [COLOR lime]CELKEM / S M3U[/COLOR][CR]"
        " – CELKEM = počet položek v Top 300 podle ČSFD[CR]"
        " – S M3U = kolik z nich má odpovídající stream v playlistu[CR]"
        "• Seriály = [COLOR lime]CELKEM[/COLOR][CR]"
        "• Další filmy z playlistu = [COLOR lime]počet filmů mimo Top 300[/COLOR]"
    )
    li_info = xbmcgui.ListItem(
        label="[COLOR gray]Legenda: Filmy = CELKEM / S M3U; Seriály = CELKEM; Další = mimo Top 300[/COLOR]"
    )
    li_info.setArt({'icon': 'DefaultInfo.png'})
    tag = li_info.getVideoInfoTag()
    tag.setTitle('Informace k počtům')
    tag.setPlot(info_text)
    xbmcplugin.addDirectoryItem(HANDLE, build_url({'action': 'noop'}), li_info, isFolder=False)

    xbmcplugin.endOfDirectory(HANDLE)

def prepare_menu():
    """
    Příprava dat — s průběžnými počty:
    - Filmy — připravit data [CELKEM / S M3U]
    - Seriály — připravit data [CELKEM]
    - Indexovat M3U → JSON (TMDb) [N_index]
    - Vyčistit cache… (dynamické velikosti)
    - Aktualizovat cache (filmy + seriály)
    """

    # --- dopočty (bez chybových dialogů; při chybě 0) ---
    try:
        total_films, matched_films = _count_films_with_playlist_match()  # CELKEM / s M3U
    except Exception:
        total_films, matched_films = 0, 0

    try:
        cnt_series = _count_toplist('series')
    except Exception:
        cnt_series = 0

    # N_index (počet položek v M3U indexu) – pokud nemáš _count_playlist_index(),
    # spočítáme to přímo z uloženého playlist_index.json.
    try:
        # pokud existuje utilita _count_playlist_index(), použij ji
        cnt_index = _count_playlist_index()  # může být definovaná u tebe
    except NameError:
        # bezpečný fallback – načti přes resources.lib.playlists.playlist_index
        try:
            from resources.lib.playlists import playlist_index
            idx = playlist_index.load_index_json() or {}
            cnt_index = (idx.get('meta') or {}).get('count', 0)
        except Exception:
            cnt_index = 0
    except Exception:
        cnt_index = 0

    films_label_count = f"{_lime(total_films)} / {_lime(matched_films)}"

    # --- cache stats ---
    try:
        stats = cache_stats()
    except Exception:
        stats = {
            'toplist_bytes': 0, 'toplist_files': 0,
            'details_bytes': 0, 'details_files': 0,
            'total_bytes': 0
        }

    lbl_total   = format_bytes(stats.get('total_bytes',   0))
    lbl_details = f"{format_bytes(stats.get('details_bytes', 0))} / {stats.get('details_files', 0)} soub."
    lbl_toplist = f"{format_bytes(stats.get('toplist_bytes', 0))} / {stats.get('toplist_files', 0)} soub."

    # --- položky menu (sjednocené helpery) ---
    # 1) Filmy — připravit data
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label=f"Filmy — připravit data {films_label_count}",
        plot=("Zpracuje toplisty pro filmy, doplní runtime, uloží JSON. "
              "Čitatel = vše, jmenovatel = s M3U streamem."),
        action='prepare_all',
        art_icon=ui_pick_icon(ADDON, 'csfd_prepare.png', 'DefaultMovies.png', ICON_DIR),
        is_folder=False,
        category='films'
    )

    # 2) Seriály — připravit data
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label=f"Seriály — připravit data {_lime(cnt_series)}",
        plot="Zpracuje toplisty pro seriály, doplní runtime, uloží JSON.",
        action='prepare_all',
        art_icon=ui_pick_icon(ADDON, 'csfd_prepare.png', 'DefaultTVShows.png', ICON_DIR),
        is_folder=False,
        category='series'
    )

    # 3) Indexovat M3U → JSON (TMDb)
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label=f"Indexovat M3U → JSON (TMDb) {_lime(cnt_index)}",
        plot=("Načte M3U playlist, vyhledá TMDb ID pro položky a uloží JSON index "
              "pro rychlé párování filmů."),
        action='prepare_m3u_index',
        art_icon=ui_pick_icon(ADDON, 'csfd_prepare.png', 'DefaultPlaylist.png', ICON_DIR),
        is_folder=False
    )

    # 4) Vyčistit cache…
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label=f"Vyčistit cache… (celkem ~ {lbl_total}; detaily ~ {lbl_details}; toplist ~ {lbl_toplist})",
        plot="Smazat uložené HTML a/nebo detaily + TMDb cache. Uvolní místo na disku.",
        action='clean_cache_menu',
        art_icon=ui_pick_icon(ADDON, 'csfd_clean.png', 'DefaultTrash.png', ICON_DIR),
        is_folder=True
    )

    # 5) Aktualizovat cache (filmy + seriály)
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label="Aktualizovat cache (filmy + seriály)",
        plot="Obnoví cache a JSONy pro obě kategorie, ukáže souhrn změn.",
        action='update_all',
        art_icon=ui_pick_icon(ADDON, 'csfd_update.png', 'DefaultFolder.png', ICON_DIR),
        is_folder=False
    )

    xbmcplugin.endOfDirectory(HANDLE)

def clean_cache_menu():
    items = [
        ("Smazat jen toplist HTML (filmy+seriály)", 'toplist',
         "Odstraní uložené stránky toplistů (0/100/200)."),
        ("Smazat jen detaily", 'details',
         "Vymaže cache detailů (runtime) a TMDb cache."),
        ("Smazat vše (toplist HTML + detaily)", 'all',
         "Kompletní vyčištění cache pro doplněk (včetně TMDb)."),
    ]
    for label, what, plot in items:
        ui_add_item(
            handle=HANDLE,
            build_url_fn=build_url,
            label=label,
            plot=plot,
            action='clean_cache',
            art_icon=ui_pick_icon(ADDON, 'csfd_clean.png', 'DefaultTrash.png', ICON_DIR),
            is_folder=False,
            what=what
        )
    xbmcplugin.endOfDirectory(HANDLE)


def browse_menu(category: str):
    # ... zůstává kontrola existence JSON s chybovým hlášením
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label="Zobrazit vše",
        plot="Vypíše všechny položky vybrané kategorie.",
        action='browse',
        art_icon=ui_pick_icon(ADDON, 'csfd_browse.png', 'DefaultFolder.png', ICON_DIR),
        is_folder=True,
        category=category
    )
    ui_add_item(
        handle=HANDLE,
        build_url_fn=build_url,
        label="Filtrovat podle země původu",
        plot="Vyber jednu či více zemí (OR filtr).",
        action='list_countries',
        art_icon=ui_pick_icon(ADDON, 'csfd_filter_country.png', 'DefaultFilter.png', ICON_DIR),
        is_folder=True,
        category=category
    )
    xbmcplugin.endOfDirectory(HANDLE)


def list_countries(category: str):
    """
    Načte JSON a zobrazí multivýběr unikátních zemí původu (abecedně, s počty).
    Po potvrzení rovnou aplikuje OR filtr (stačí 1 vybraná země) a vykreslí seznam.
    """
    try:
        items = load_json(category)
    except Exception as e:
        log.error(f"Chyba čtení JSON: {e}")
        xbmcgui.Dialog().notification("ČSFD Toplist", "Chyba čtení JSON (viz log).", xbmcgui.NOTIFICATION_ERROR, 5000)
        xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
        return

    from collections import Counter
    counts = Counter()
    for it in items:
        for c in (it.get('countries') or []):
            name = (c or '').strip()
            if name:
                counts[name] += 1

    if not counts:
        xbmcgui.Dialog().notification("ČSFD Toplist", "V JSON nejsou uvedeny žádné země.", xbmcgui.NOTIFICATION_INFO, 3000)
        xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
        return

    countries = sorted(counts.keys(), key=lambda s: s.casefold())
    labels = [f"{c} ({counts[c]})" for c in countries]
    dlg = xbmcgui.Dialog()
    selection = dlg.multiselect("Vyber zemi/zeme (OR filtr)", labels, useDetails=False)

    # Uživatel zavřel dialog bez potvrzení
    if selection is None:
        xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
        return

    # Žádná země vybrána -> zobraz vše
    if not selection:
        render_items(items, is_tv=(category == 'series'))
        return

    # Sestav množinu vybraných zemí (normalizovaně přes casefold)
    selected = [countries[i] for i in selection]
    wanted = { s.casefold().strip() for s in selected if s and s.strip() }

    # OR filtr
    filtered = []
    for it in items:
        c_list = [ (c or '').strip().casefold() for c in (it.get('countries') or []) ]
        if any(c in wanted for c in c_list):
            filtered.append(it)

    if not filtered:
        xbmcgui.Dialog().notification("ČSFD Toplist", "Žádné položky pro zvolený filtr zemí.", xbmcgui.NOTIFICATION_INFO, 3000)
        xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
        return

    render_items(filtered, is_tv=(category == 'series'))


def do_clean_cache(what: str):
    """
    Provede mazání cache a ukáže, kolik místa se uvolnilo.
    """
    # Změřit stav PŘED
    try:
        before = cache_stats()
    except Exception:
        before = {'toplist_bytes': 0, 'details_bytes': 0, 'total_bytes': 0, 'toplist_files':0, 'details_files':0}

    toplist = (what in ('toplist', 'all'))
    details = (what in ('details', 'all'))
    res = clean_cache(toplist_html=toplist, details=details)

    # Změřit stav PO
    try:
        after = cache_stats()
    except Exception:
        after = {'toplist_bytes': 0, 'details_bytes': 0, 'total_bytes': 0, 'toplist_files':0, 'details_files':0}

    freed_total   = max(0, (before.get('total_bytes', 0)   - after.get('total_bytes', 0)))
    freed_details = max(0, (before.get('details_bytes', 0) - after.get('details_bytes', 0)))
    freed_toplist = max(0, (before.get('toplist_bytes', 0) - after.get('toplist_bytes', 0)))

    msg = []
    if toplist:
        msg.append(f"Toplist HTML: smazáno {res.get('toplist_deleted',0)} souborů, uvolněno ~ {format_bytes(freed_toplist)}")
    if details:
        msg.append(f"Detaily/TMDb: uvolněno ~ {format_bytes(freed_details)}")
    msg.append(f"Celkem uvolněno ~ {format_bytes(freed_total)}")

    xbmcgui.Dialog().ok("ČSFD Toplist – Cache", "\n".join(msg) or "Hotovo.")
    prepare_menu()


def do_prepare_all(category: str):
    """
    Kompletní příprava v jednom kroku s progress barem:
    - stáhnout toplist HTML (0/100/200) do cache
    - parsovat + sloučit
    - doplnit runtime z detailů (cache + stáhnout chybějící)
    - TMDb obohacení (CZ -> EN fallback), uložit do JSON
    - zobrazit diff (+/-) oproti předchozímu snapshotu kategorie
    - zobrazit výpis
    """
    # starý snapshot pro diff (pokud existuje)
    def try_load(cat: str):
        try:
            return load_json(cat)
        except Exception:
            return []
    old_items = try_load(category)

    dp = xbmcgui.DialogProgress()
    dp.create("ČSFD Toplist – Příprava dat", "Inicializace…")
    cancelled = False

    def progress_cb(percent: int, message: str):
        nonlocal cancelled
        if cancelled:
            return
        cancelled = dp.iscanceled()
        if not cancelled:
            dp.update(max(0, min(100, int(percent))), message)

    try:
        items = prepare_all_with_progress(
            category=category,
            fetch_html=True,
            fetch_details=True,
            progress=progress_cb
        )
        if cancelled:
            xbmcgui.Dialog().notification("ČSFD Toplist", "Operace zrušena.", xbmcgui.NOTIFICATION_INFO, 3000)
            xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
            return

        # diff proti starému snapshotu
        # Zobrazit diff souhrn
        from resources.lib.csfd_toplist.scraper import diff_by_id
        diff = diff_by_id(old_items, items)

        # ulož, ukaž souhrn, pak list
        save_json(category, items)
        dp.update(100, "Hotovo. Zobrazuji souhrn změn…")
        dp.close()

        lines = [
            "Příprava dokončena.",
            "",
            f"{'Seriály' if category=='series' else 'Filmy'}:",
            f" +{diff['added']} / -{diff['removed']}",
        ]
        xbmcgui.Dialog().ok("ČSFD Toplist – Příprava (souhrn)", "\n".join(lines))
        render_items(items, is_tv=(category == 'series'))

    except Exception as e:
        try:
            dp.close()
        except:
            pass
        log.error(f"Chyba prepare_all: {e}")
        xbmcgui.Dialog().notification("ČSFD Toplist", "Chyba přípravy (viz log).", xbmcgui.NOTIFICATION_ERROR, 5000)
        xbmcplugin.endOfDirectory(HANDLE, succeeded=False)


def do_update_all():
    """
    Aktualizuje cache i JSONy pro FILMY i SERIÁLY (bez mazání cache):
    - stáhne znovu toplist HTML (0/100/200) pro obě kategorie,
    - doplní runtime z detailů (stáhne jen chybějící),
    - TMDb obohacení (CZ -> EN fallback),
    - uloží csfd_filmy.json a csfd_serialy.json,
    - zobrazí souhrn: přidané / odebrané položky (diff oproti dřívějším JSONům).
    """
    def try_load(category: str):
        try:
            return load_json(category)
        except Exception:
            return []

    old_films = try_load('films')
    old_series = try_load('series')

    dp = xbmcgui.DialogProgress()
    dp.create("ČSFD Toplist – Aktualizace cache", "Inicializace…")
    cancelled = False

    def map_progress(base: int, span: int, pct_in: int) -> int:
        return base + int(span * max(0, min(100, pct_in)) / 100)

    from resources.lib.csfd_toplist.scraper import diff_by_id

    try:
        # Filmy 0–50 %
        def prog_films(p, msg):
            nonlocal cancelled
            if not cancelled:
                dp.update(map_progress(0, 50, p), f"[Filmy] {msg}")
        items_films = prepare_all_with_progress('films', fetch_html=True, fetch_details=True, progress=prog_films)
        if dp.iscanceled():
            cancelled = True
            dp.close()
            xbmcgui.Dialog().notification("ČSFD Toplist", "Aktualizace zrušena.", xbmcgui.NOTIFICATION_INFO, 3000)
            xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
            return
        diff_films = diff_by_id(old_films, items_films)
        save_json('films', items_films)

        # Seriály 50–100 %
        def prog_series(p, msg):
            nonlocal cancelled
            if not cancelled:
                dp.update(map_progress(50, 50, p), f"[Seriály] {msg}")
        items_series = prepare_all_with_progress('series', fetch_html=True, fetch_details=True, progress=prog_series)
        if dp.iscanceled():
            cancelled = True
            dp.close()
            xbmcgui.Dialog().notification("ČSFD Toplist", "Aktualizace zrušena.", xbmcgui.NOTIFICATION_INFO, 3000)
            xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
            return
        diff_series = diff_by_id(old_series, items_series)
        save_json('series', items_series)

        dp.update(100, "Hotovo. JSONy aktualizovány.")
        dp.close()

        lines = [
            "Aktualizace dokončena.",
            "",
            f"Filmy: +{diff_films['added']} / -{diff_films['removed']}",
            f"Seriály: +{diff_series['added']} / -{diff_series['removed']}",
        ]
        xbmcgui.Dialog().ok("ČSFD Toplist – Aktualizace", "\n".join(lines))
        prepare_menu()

    except Exception as e:
        try:
            dp.close()
        except:
            pass
        log.error(f"Chyba update_all: {e}")
        xbmcgui.Dialog().notification("ČSFD Toplist", "Chyba aktualizace (viz log).", xbmcgui.NOTIFICATION_ERROR, 5000)
        xbmcplugin.endOfDirectory(HANDLE, succeeded=False)

# -------------------------------- router --------------------------------------
def router(paramstring):
    params = urlparse.parse_qs(paramstring[1:])
    action = params.get('action', [None])[0]
    if action is None:
        root_menu(); return

    if action == 'prepare_menu':
        prepare_menu(); return

    if action == 'clean_cache_menu':
        clean_cache_menu(); return

    if action == 'clean_cache':
        what = params.get('what', ['all'])[0]
        do_clean_cache(what); return

    if action == 'prepare_all':
        category = (params.get('category', ['films'])[0]).lower()
        do_prepare_all(category); return

    if action == 'update_all':
        do_update_all(); return

    if action == 'browse_menu':
        category = (params.get('category', ['series'])[0]).lower()
        browse_menu(category); return

    if action == 'list_countries':
        category = (params.get('category', ['series'])[0]).lower()
        list_countries(category); return

    if action == 'browse_filtered':
        category = (params.get('category', ['series'])[0]).lower()
        # podpora 1 i více zemí (oddělené '\n')
        multi = params.get('countries', [None])[0]
        single = params.get('country', [None])[0]
        try:
            items = load_json(category)
        except Exception as e:
            log.error(f"Chyba čtení JSON: {e}")
            xbmcgui.Dialog().notification("ČSFD Toplist", "Chyba čtení JSON (viz log).", xbmcgui.NOTIFICATION_ERROR, 5000)
            xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
            return

        # Sestav množinu hledaných zemí (case-insensitive)
        wanted = set()
        if multi:
            for c in (multi.split('\n') if multi else []):
                c = (c or '').strip()
                if c:
                    wanted.add(c.lower())
        elif single:
            s = (single or '').strip()
            if s:
                wanted.add(s.lower())

        if not wanted:
            # Bez vybraných zemí → zobraz vše
            render_items(items, is_tv=(category == 'series'))
            return

        # OR filtr
        filtered = []
        for it in items:
            c_list = [ (c or '').strip().lower() for c in (it.get('countries') or []) ]
            if any(c in wanted for c in c_list):
                filtered.append(it)

        if not filtered:
            xbmcgui.Dialog().notification("ČSFD Toplist", "Žádné položky pro zvolený filtr zemí.", xbmcgui.NOTIFICATION_INFO, 3000)
            xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
            return

        render_items(filtered, is_tv=(category == 'series'))
        return

    if action == 'browse':
        category = (params.get('category', ['series'])[0]).lower()
        try:
            items = load_json(category)
        except FileNotFoundError as e:
            xbmcgui.Dialog().notification(
                "ČSFD Toplist",
                f"{e}\nOtevři prosím 'Příprava dat' a JSON nejdřív vytvoř.",
                xbmcgui.NOTIFICATION_ERROR, 5000
            )
            xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
            return
        except Exception as e:
            log.error(f"Chyba browse: {e}")
            xbmcgui.Dialog().notification("ČSFD Toplist", "Chyba čtení JSON (viz log).", xbmcgui.NOTIFICATION_ERROR, 5000)
            xbmcplugin.endOfDirectory(HANDLE, succeeded=False)
            return

        render_items(items, is_tv=(category == 'series')); return


if __name__ == '__main__':
    router(sys.argv[2])