# -*- coding: utf-8 -*-
import xbmc
import xbmcgui
import xbmcplugin
import xbmcaddon
from urllib.parse import quote
import os

from resources.lib.utils.ui_utils import make_static_item, add_menu_item, pick_icon
from resources.lib.utils.log_utils import get_logger
from datetime import datetime

log = get_logger()

def trakt_search_dialog(get_url_fn):
    """
    Zobrazí vyhledávací dialog Kodi a spustí vyhledávání na Trakt.tv.
    """
    query = xbmcgui.Dialog().input(
        'Hledej na Trakt.tv (Název filmu/seriálu)', 
        type=xbmcgui.INPUT_TYPE_TEXT
    )
    
    if not query:
        return

    url = get_url_fn(action='trakt_search_results', query=query)
    xbmc.executebuiltin(f'Container.Update({url})')

def movies_menu(handle, addon, get_url_fn):
    """Podmenu pro sekci Filmy: Naposledy sledované + Stažené filmy + Historie."""
    xbmcplugin.setPluginCategory(handle, "Filmy")

    # 1) Naposledy sledované filmy
    li_history_movies = make_static_item(
        label="Naposledy sledované filmy",
        plot=(
            "Zobrazí seznam naposledy sledovaných filmů.\n"
            "• Umožní rychlé opakování přehrávání.\n"
            "• Data jsou z lokální historie doplňku."
        ),
        addon=addon,
        icon_name='recent_movies.png',
        default_icon='DefaultRecentlyAddedMovies.png'
    )
    xbmcplugin.addDirectoryItem(
        handle,
        get_url_fn(action='watch_history_list', type='movie'),
        li_history_movies,
        isFolder=True
    )

    # 2) Stažené filmy
    li_downloaded = make_static_item(
        label="Stažené filmy",
        plot=(
            "Zobrazí seznam filmů stažených do offline složky.\n"
            "• Umožní přehrávání bez internetu.\n"
            "• Možnost mazání souborů."
        ),
        addon=addon,
        icon_name='downloaded.png',
        default_icon='DefaultHardDisk.png'
    )
    xbmcplugin.addDirectoryItem(
        handle,
        get_url_fn(action='movies_downloaded'),
        li_downloaded,
        isFolder=True
    )

    # 3) Sledovat později (Webshare Watchlist)
    li_watchlist = make_static_item(
        label="Sledovat později",
        plot=(
            "Zobrazí seznam filmů, které sis označil(a) pro pozdější zhlédnutí.\n"
            "• Položky jsou řazeny dle data přidání.\n"
            "• Snadné odebrání ze seznamu."
        ),
        addon=addon,
        icon_name='watchlist.png',
        default_icon='DefaultFavourites.png'
    )
    xbmcplugin.addDirectoryItem(
        handle,
        get_url_fn(action='watchlist_list', type='movie'),
        li_watchlist,
        isFolder=True
    )

    # 4) Historie (Webshare)
    li_ws_history = make_static_item(
        label="Historie",
        plot=(
            "Historie přehrávání a stahování z Webshare.\n"
            "• Lze znovu přehrát položky nebo je vyčistit.\n"
            "• Stejné jako https://webshare.cz/#/history"
        ),
        addon=addon,
        icon_name='watched.png',
        default_icon='DefaultRecentlyAddedEpisodes.png'
    )
    xbmcplugin.addDirectoryItem(
        handle,
        get_url_fn(action='history'),
        li_ws_history,
        isFolder=True
    )
    xbmcplugin.endOfDirectory(handle)

def _yescolor(flag: bool) -> str:
    return "[COLOR lime]Zapnuto[/COLOR]" if flag else "[COLOR red]Vypnuto[/COLOR]"

def _short(path: str, fallback: str = "Nenastaveno") -> str:
    if not path:
        return fallback
    p = str(path).replace("\\", "/").rstrip("/")
    parts = p.split("/")
    return "/".join(parts[-2:]) if len(parts) >= 2 else p


AUTHOR_PIN = "12345"


def _is_author_pin_ok(addon) -> bool:
    return (addon.getSetting('author_pin') or '').strip() == AUTHOR_PIN

def show_experimental_menu(handle, addon, get_url_fn):
    xbmcplugin.setPluginCategory(handle, "Nástroje a údržba")

    def _get_bool(k, default=False):
        try:
            return addon.getSettingBool(k)
        except Exception:
            return (addon.getSetting(k) or "").lower() == "true" if addon.getSetting(k) is not None else default

    enable_lib = _get_bool('enable_library_export', False)
    enable_m3u = _get_bool('enable_m3u_library', False)
    force_m3u  = _get_bool('m3u_export_force', False)
    playlist   = addon.getSetting('playlist_path') or ''
    author_mode_enabled = _get_bool('author_mode_enabled', False)
    author_pin_ok = _is_author_pin_ok(addon)
    author_mode = author_mode_enabled and author_pin_ok

    def _can_show_author_item(flag_key):
        return author_mode and _get_bool(flag_key, False)

    # --- Záloha nastavení (viditelné všem) ---
    try:
        from resources.lib.utils.settings_backup import device_id
        _did = device_id(addon)
    except Exception:
        _did = "?"

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='Zálohovat nastavení',
        plot=(
            "Uloží lokální kopii settings.xml (3 rotující zálohy) "
            f"a při zapnutém CloudSync nahraje per-device zálohu na FTP "
            f"(toto zařízení: {_did})."
        ),
        action='settings_backup_now',
        art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
        is_folder=False
    )

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='Obnovit nastavení…',
        plot=(
            "Obnoví settings.xml z lokální zálohy nebo z CloudSync FTP "
            "(slot tohoto zařízení, případně jiné — s varováním o cestách). "
            "Po obnově je potřeba restartovat Kodi."
        ),
        action='settings_restore_menu',
        art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
        is_folder=False
    )

    if author_pin_ok:
        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label=f"Autorský režim: {_yescolor(author_mode_enabled)}",
            plot=(
                "Zapne/vypne interní autorské volby. "
                "Položka je dostupná jen při správném Autorském PINu "
                "v Nastavení > Pokročilé a Systémové."
            ),
            action='exp_toggle_bool',
            art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
            is_folder=False, key='author_mode_enabled'
        )

    if author_mode:
        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label=f"Knihovna Kodi (.strm): {_yescolor(enable_lib)}",
            plot="Zapne/vypne export seriálů do Kodi knihovny (.strm).",
            action='exp_toggle_bool',
            art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
            is_folder=False, key='enable_library_export'
        )

        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label=f"M3U → Knihovna (.strm): {_yescolor(enable_m3u)}",
            plot="Zapne/vypne export filmů z playlistu M3U do Kodi knihovny (.strm).",
            action='exp_toggle_bool',
            art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
            is_folder=False, key='enable_m3u_library'
        )

        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label=f"Force M3U export: {_yescolor(force_m3u)}",
            plot="Při exportu z M3U ignoruje změny a přegeneruje vše.",
            action='exp_toggle_bool',
            art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
            is_folder=False, key='m3u_export_force'
        )

        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label=f"Cesta k playlistu M3U: [COLOR gold]{_short(playlist)}[/COLOR]",
            plot="Vyber soubor playlistu (.m3u / .m3u8).",
            action='exp_browse_file',
            art_icon=pick_icon(addon, 'folder.png', 'DefaultFolder.png'),
            is_folder=False, key='playlist_path'
        )

        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label='Telemetry: Start log (cloud)',
            plot='Podmenu měsíců z _telemetry/YYYY-MM.jsonl — výpis startů všech zařízení.',
            action='telemetry_months_menu',
            art_icon=pick_icon(addon, 'log.png', 'DefaultAddonService.png'),
            is_folder=True
        )

        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label='Telemetry: Nahrát nyní (force)',
            plot='Okamžitě appendne pending telemetrii do _telemetry/YYYY-MM.jsonl.',
            action='telemetry_upload_now',
            art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
            is_folder=False
        )

        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label='Telemetry: Migrovat cloud data',
            plot='Sloučí staré all_users-* a per-install start-* do _telemetry/YYYY-MM.jsonl (1×).',
            action='telemetry_migrate_cloud',
            art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
            is_folder=False
        )

    try:
        from resources.lib.utils.background_enrich import get_last_tmdb_audit_time
        last_ts = get_last_tmdb_audit_time()
        last_str = datetime.fromtimestamp(last_ts).strftime('%d.%m %H:%M') if last_ts > 0 else 'nikdy'
    except Exception:
        last_str = '?'

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label=f'TMDb audit & doplnění metadat [COLOR gold](naposledy: {last_str})[/COLOR]',
        plot='Projede celou DB: opraví title_cs/title_en (latinka), doplní overview_cs/en, rok, poster, backdrop.',
        action='tmdb_audit_fill',
        art_icon=pick_icon(addon, 'tmdb.png', 'DefaultPicture.png', 'tmdb'),
        is_folder=False
    )

    if _can_show_author_item('exp_show_tmdb_full_audit'):
        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label='TMDb kompletní audit [COLOR orange](ignoruje auto-skip + CZ flag)[/COLOR]',
            plot='Vynutí kompletní audit všech movie/tv záznamů bez ohledu na tmdb_audit_skip a cz_unavailable.',
            action='tmdb_audit_fill_full',
            art_icon=pick_icon(addon, 'tmdb.png', 'DefaultPicture.png', 'tmdb'),
            is_folder=False
        )

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='Zobrazit log doplňku (posl. 100 řádků)',
        plot='Zobrazí posledních 100 relevantních řádků z Kodi logu filtrovaných pro tento doplněk (SM2- + ERRORy).',
        action='show_kodi_log',
        art_icon=pick_icon(addon, 'log.png', 'DefaultAddonService.png'),
        is_folder=False
    )

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='Uložit log doplňku do souboru',
        plot='Uloží posledních 100 relevantních řádků logu do souboru sm2_log.txt v profilu doplňku. Po uložení zobrazí cestu k souboru.',
        action='save_kodi_log',
        art_icon=pick_icon(addon, 'log.png', 'DefaultAddonService.png'),
        is_folder=False
    )

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='Vymazat Menu Cache',
        plot='Vymaže celou L1 menu cache (Window properties). Nutné po změnách v nastavení nebo pro vynucení čerstvých dat menu.',
        action='clear_menu_cache',
        art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
        is_folder=False
    )

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='Spustit offline scan složek (force)',
        plot=(
            'Okamžitě projde složku stažených seriálů (nastavení dfolder), '
            'aktualizuje tabulku offline_cache v DB a zobrazí souhrn. '
            'Použij po ručním nakopírování nebo smazání souborů. '
            'Podrobný průběh je v Kodi logu (prefix [OfflineScanner][DBG]).'
        ),
        action='offline_scan_now',
        art_icon=pick_icon(addon, 'folder.png', 'DefaultFolder.png'),
        is_folder=False
    )

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='Vymazat cache ffprobe / titulků (vše)',
        plot='Vymaže celý soubor subcaps_cache.json (výsledky detekce jazyků streamů u seriálů). Po výmazu proběhne znovu detekce při dalším skenu.',
        action='subcaps_clear_all',
        art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
        is_folder=False
    )

    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='Vymazat cache ffprobe pro jeden seriál…',
        plot='Výběr seriálu podle uloženého series_name v cache; lze také smazat jen staré záznamy bez přiřazeného seriálu.',
        action='subcaps_clear_series_menu',
        art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
        is_folder=False
    )

    if _can_show_author_item('exp_show_reextract_features'):
        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label='Přepočítat features (CZdab/CZtit/HDR/…) ve všech seriálech',
            plot=(
                'Projede všechny uložené seriály v DB (series_data) a u každého streamu '
                'znovu spočítá pole "features". '
                'Pro proskenované streamy (subcaps_cache.is_probed) je autoritativní '
                'výsledek ffprobe / http_range_probe — CZdab/CZtit se odvodí přesně '
                'podle nalezených audio/sub stop, ne podle názvu souboru. '
                'Pro neproskenované streamy se použije filename heuristika '
                '(StreamCurator.extract_features) jako fallback. '
                'Ostatní featury (HDR/5.1/HEVC/2160p/…) zůstávají beze změny. '
                'Probíhá v hlavním vlákně s progress dialogem; bez síťového volání.'
            ),
            action='series_reextract_features',
            art_icon=pick_icon(addon, 'toggle.png', 'DefaultAddonService.png'),
            is_folder=False
        )

    xbmcplugin.endOfDirectory(handle)

def exp_toggle_bool(addon, key: str):
    if not key:
        xbmcgui.Dialog().notification(addon.getAddonInfo('name'), "Chybí klíč nastavení.", xbmcgui.NOTIFICATION_ERROR, 2500)
        return
    try:
        try:
            cur = addon.getSettingBool(key)
            addon.setSettingBool(key, not cur)
            newv = not cur
        except Exception:
            cur = (addon.getSetting(key) or "").lower() == "true"
            addon.setSetting(key, "true" if (not cur) else "false")
            newv = (not cur)
        xbmcgui.Dialog().notification("Nastavení", f"{key}: {'Zapnuto' if newv else 'Vypnuto'}", xbmcgui.NOTIFICATION_INFO, 2000)
    except Exception as e:
        xbmcgui.Dialog().notification("Nastavení", f"Chyba: {e}", xbmcgui.NOTIFICATION_ERROR, 3000)
    xbmc.executebuiltin('Container.Refresh')


def _subcaps_human_title_for_storage_key(addon, profile, storage_key: str) -> str:
    """Název seriálu z DB (name / TMDb), jinak původní klíč (tmdb_… / safe_name)."""
    if not storage_key:
        return ""
    try:
        from resources.lib.series import series_manager
        sm = series_manager.SeriesManager(addon, profile)
        data = sm.load_series_data(storage_key)
        if not isinstance(data, dict):
            return storage_key
        nm = (data.get("name") or "").strip()
        tmdb = data.get("tmdb") or {}
        if not nm:
            nm = (tmdb.get("title") or tmdb.get("original_title") or "").strip()
        if nm:
            return nm
    except Exception as ex:
        log.debug(f"_subcaps_human_title_for_storage_key {storage_key!r}: {ex}")
    return storage_key


def subcaps_clear_series_dialog(addon):
    """Dialog výběru seriálu / legacy záznamů pro částečný výmaz subcaps cache."""
    import xbmcvfs
    from resources.lib.series import subcaps_cache

    profile = xbmcvfs.translatePath(addon.getAddonInfo("profile"))

    try:
        names, legacy_count = subcaps_cache.list_series_in_cache()
    except Exception as e:
        log.warning(f"subcaps list_series_in_cache: {e}")
        xbmcgui.Dialog().notification(
            addon.getAddonInfo("name"),
            f"Chyba čtení cache: {e}",
            xbmcgui.NOTIFICATION_ERROR,
            3000,
        )
        return

    if not names and legacy_count == 0:
        xbmcgui.Dialog().notification(
            addon.getAddonInfo("name"),
            "Subcaps cache je prázdná.",
            xbmcgui.NOTIFICATION_INFO,
            2500,
        )
        return

    # Popisky v seznamu: lidský název; při kolizi stejného názvu doplnit klíč
    from collections import Counter
    raw_titles = [_subcaps_human_title_for_storage_key(addon, profile, sk) for sk in names]
    title_counts = Counter(raw_titles)
    options = []
    for sk, t in zip(names, raw_titles):
        if title_counts[t] > 1:
            options.append("{}  [{}]".format(t, sk))
        else:
            options.append(t)

    legacy_idx = -1
    if legacy_count > 0:
        legacy_idx = len(options)
        options.append(
            "[Bez přiřazeného seriálu — staré záznamy] ({})".format(legacy_count)
        )

    idx = xbmcgui.Dialog().select("Vymazat cache ffprobe pro…", options)
    if idx < 0:
        return

    if legacy_idx >= 0 and idx == legacy_idx:
        if not xbmcgui.Dialog().yesno(
            "Potvrdit",
            "Smazat {} záznamů bez přiřazeného seriálu?".format(legacy_count),
            nolabel="Zpět",
            yeslabel="Smazat",
        ):
            return
        n = subcaps_cache.remove_entries_without_series()
    else:
        sn = names[idx]
        display = raw_titles[idx]
        confirm_lines = "Smazat všechny záznamy cache pro seriál:\n{}".format(display)
        if display != sn:
            confirm_lines += "\n({})".format(sn)
        if not xbmcgui.Dialog().yesno(
            "Potvrdit",
            confirm_lines,
            nolabel="Zpět",
            yeslabel="Smazat",
        ):
            return
        n = subcaps_cache.remove_entries_for_series(sn)

    xbmcgui.Dialog().notification(
        "Subcaps cache",
        "Smazáno záznamů: {}".format(n),
        xbmcgui.NOTIFICATION_INFO,
        2500,
    )
    xbmc.executebuiltin("Container.Refresh")


def _recompute_stream_features(
    st, stream_curator_cls, subcaps_cache_mod,
    normalize_language_features_fn, cz_dab, cz_tit,
):
    """Přepočte features jednoho streamu podle nové priority:

    1) Pokud `subcaps_cache.is_probed(ident)` → cache je autoritativní:
       - vezmi filename featury **bez** CZ jazykových tagů,
       - přidej `CZdab` / `CZtit` výhradně podle cache,
       - audio_badges / video_badges z cache se sloučí (pro doplnění
         5.1 / Atmos / 2160p / HDR / DV detekovaných probem).
    2) Jinak → klasické `extract_features` (filename heuristika).
    """
    ident = st.get('ident')
    raw_filename = list(stream_curator_cls.extract_features(st) or [])

    if not ident or not subcaps_cache_mod.is_probed(ident):
        return raw_filename

    non_cz = [
        f for f in normalize_language_features_fn(raw_filename)
        if f not in (cz_dab, cz_tit)
    ]

    try:
        for b in (subcaps_cache_mod.audio_badges(ident) or []):
            if b == cz_dab:
                continue
            if b not in non_cz:
                non_cz.append(b)
    except Exception:
        pass
    try:
        for b in (subcaps_cache_mod.video_badges(ident) or []):
            if b not in non_cz:
                non_cz.append(b)
    except Exception:
        pass

    out = list(non_cz)
    if subcaps_cache_mod.has_cz_audio(ident):
        out.insert(0, cz_dab)
    if subcaps_cache_mod.has_cz_subs(ident):
        insert_at = 1 if (out and out[0] == cz_dab) else 0
        out.insert(insert_at, cz_tit)
    return out


def series_reextract_features_dialog(addon):
    """Projede všechny uložené seriály v DB a přepočítá `features` u všech
    streamů. Pro proskenované streamy je autoritativní subcaps cache
    (ffprobe / http_range_probe), pro neproskenované fallback na
    `StreamCurator.extract_features` (filename heuristika).
    Zapisuje přes `SeriesManager._save_series_data` (přepočítá `_content_hash`).

    Cíl: odstranit z DB legacy false-positive `CZ` / `CZ-SK` / `CZ-EN`
    tokeny i CZdab/CZtit z filename heuristiky tam, kde probe ukázal
    skutečný stav audio/sub stop.
    """
    import xbmcvfs
    from resources.lib.series.series_manager import SeriesManager
    from resources.lib.series.series_curator import StreamCurator
    from resources.lib.series.series_helpers import (
        CZ_DAB,
        CZ_TIT,
        normalize_language_features,
    )
    from resources.lib.series import subcaps_cache

    if not xbmcgui.Dialog().yesno(
        'Přepočítat features',
        'Projít všechny seriály v DB a přepočítat features (CZdab/CZtit/HDR/…)? '
        'Pro proskenované streamy se použije autoritativní výsledek probe '
        '(ffprobe / http_range_probe), pro ostatní filename heuristika. '
        'Nemění kvalitu/ident/score a nevolá síť.',
        nolabel='Zpět',
        yeslabel='Spustit',
    ):
        return

    profile = xbmcvfs.translatePath(addon.getAddonInfo("profile"))
    sm = SeriesManager(addon, profile)
    series_list = sm.get_all_series() or []
    total = len(series_list)
    if total == 0:
        xbmcgui.Dialog().notification(
            addon.getAddonInfo('name'),
            'Žádné seriály v DB.',
            xbmcgui.NOTIFICATION_INFO,
            2500,
        )
        return

    dlg = xbmcgui.DialogProgress()
    dlg.create('Přepočet features', 'Inicializace…')

    series_changed = 0
    streams_total = 0
    streams_changed = 0
    series_failed = 0

    try:
        for idx, entry in enumerate(series_list):
            if dlg.iscanceled():
                break
            display = entry.get('name') or entry.get('safe_name') or '?'
            safe_name = entry.get('safe_name') or entry.get('name') or ''
            pct = int((idx / max(total, 1)) * 100)
            # Kodi Matrix+ DialogProgress.update přijímá jen (percent, message) —
            # víceřádkový label se předává jako jeden string s `\n`.
            dlg.update(pct, f'{idx + 1}/{total}\n{display}')

            try:
                data = sm.load_series_data(safe_name)
            except Exception as ex:
                log.warning(f"reextract: load fail {safe_name!r}: {ex}")
                series_failed += 1
                continue
            if not isinstance(data, dict):
                continue

            seasons = data.get('seasons') or {}
            if not isinstance(seasons, dict):
                continue

            local_changed = False
            for s_key in list(seasons.keys()):
                ep_dict = seasons.get(s_key) or {}
                if not isinstance(ep_dict, dict):
                    continue
                for e_key in list(ep_dict.keys()):
                    ep = ep_dict.get(e_key) or {}
                    if not isinstance(ep, dict):
                        continue
                    streams = ep.get('streams') or []
                    if not isinstance(streams, list):
                        continue
                    for st in streams:
                        if not isinstance(st, dict):
                            continue
                        streams_total += 1
                        try:
                            new_feats = _recompute_stream_features(
                                st, StreamCurator, subcaps_cache,
                                normalize_language_features, CZ_DAB, CZ_TIT,
                            )
                        except Exception as ex:
                            log.warning(
                                f"reextract: recompute fail "
                                f"{safe_name!r} S{s_key}E{e_key}: {ex}"
                            )
                            continue
                        old_feats = list(st.get('features') or [])
                        if new_feats != old_feats:
                            st['features'] = new_feats
                            streams_changed += 1
                            local_changed = True

            if local_changed:
                try:
                    sm._save_series_data(safe_name, data)
                    series_changed += 1
                except Exception as ex:
                    log.warning(f"reextract: save fail {safe_name!r}: {ex}")
                    series_failed += 1
    finally:
        try:
            dlg.close()
        except Exception:
            pass

    log.info(
        f"reextract features summary series={series_changed}/{total} "
        f"streams={streams_changed}/{streams_total} failed={series_failed}"
    )

    xbmcgui.Dialog().ok(
        'Přepočet features hotov',
        'Seriály změněny: {} / {}\n'
        'Streamy změněny: {} / {}\n'
        'Chyby: {}'.format(
            series_changed, total, streams_changed, streams_total, series_failed
        ),
    )
    xbmc.executebuiltin('Container.Refresh')


def exp_browse_file(addon, key: str):
    import xbmcvfs
    if not key:
        xbmcgui.Dialog().notification(addon.getAddonInfo('name'), "Chybí klíč nastavení.", xbmcgui.NOTIFICATION_ERROR, 2500)
        return
    try:
        path = xbmcgui.Dialog().browse(1, "Vyber playlist M3U", "files", mask="*.m3u|*.m3u8")
        if path:
            try:
                resolved = xbmcvfs.translatePath(path) if path.startswith("special://") else path
            except Exception:
                resolved = path
            addon.setSetting(key, resolved)
            xbmcgui.Dialog().notification("Nastavení", "Cesta uložena.", xbmcgui.NOTIFICATION_INFO, 2000)
        else:
            xbmcgui.Dialog().notification("Nastavení", "Výběr zrušen.", xbmcgui.NOTIFICATION_INFO, 1500)
    except Exception as e:
        xbmcgui.Dialog().notification("Nastavení", f"Chyba výběru: {e}", xbmcgui.NOTIFICATION_ERROR, 3000)
    xbmc.executebuiltin('Container.Refresh')


def telemetry_months_menu(handle, addon, get_url_fn):
    """Podmenu: výběr měsíce z cloud telemetry souborů."""
    from resources.lib.utils import telemetry

    xbmcplugin.setPluginCategory(handle, "Telemetry — měsíce")

    months = telemetry.list_cloud_months(addon)
    add_menu_item(
        handle=handle, build_url_fn=get_url_fn,
        label='[B]Všechny měsíce[/B]',
        plot='Sloučený výpis ze všech _telemetry/YYYY-MM.jsonl na FTP.',
        action='telemetry_view_start_log',
        art_icon=pick_icon(addon, 'log.png', 'DefaultAddonService.png'),
        is_folder=False,
    )

    if not months:
        add_menu_item(
            handle=handle, build_url_fn=get_url_fn,
            label='(Žádné měsíční soubory na FTP)',
            plot='Na cloudu zatím nejsou _telemetry/YYYY-MM.jsonl.',
            action='telemetry_months_menu',
            art_icon=pick_icon(addon, 'log.png', 'DefaultAddonService.png'),
            is_folder=False,
        )
    else:
        _cz = {
            "01": "Leden", "02": "Únor", "03": "Březen", "04": "Duben",
            "05": "Květen", "06": "Červen", "07": "Červenec", "08": "Srpen",
            "09": "Září", "10": "Říjen", "11": "Listopad", "12": "Prosinec",
        }
        for month in months:
            y, m = month.split("-", 1)
            label = "{} {} ({})".format(_cz.get(m, m), y, month)
            add_menu_item(
                handle=handle, build_url_fn=get_url_fn,
                label=label,
                plot='Výpis startů ze souboru _telemetry/{}.jsonl.'.format(month),
                action='telemetry_view_start_log',
                art_icon=pick_icon(addon, 'log.png', 'DefaultAddonService.png'),
                is_folder=False,
                month=month,
            )

    xbmcplugin.endOfDirectory(handle)


def telemetry_view_start_log(addon, month=None):
    from resources.lib.utils import telemetry
    month = (month or "").strip() or None
    txt = telemetry.read_cloud_start_log(addon, month=month)
    title = "Telemetry {}".format(month) if month else "Telemetry — všechny měsíce"
    xbmcgui.Dialog().textviewer(title, txt, usemono=True)


def telemetry_upload_now(addon):
    from resources.lib.utils import telemetry
    ok = telemetry.upload_now(addon)
    xbmcgui.Dialog().notification(
        addon.getAddonInfo('name'),
        'Telemetry upload OK.' if ok else 'Telemetry upload selhal (viz log).',
        xbmcgui.NOTIFICATION_INFO if ok else xbmcgui.NOTIFICATION_WARNING,
        3000,
    )
    xbmc.executebuiltin('Container.Refresh')


def telemetry_migrate_cloud(addon):
    from resources.lib.utils import telemetry
    ok, msg = telemetry.migrate_cloud_data(addon)
    xbmcgui.Dialog().textviewer(
        'Telemetry migrace cloudu',
        msg or ('OK' if ok else 'Selhalo'),
        usemono=True,
    )
    xbmcgui.Dialog().notification(
        addon.getAddonInfo('name'),
        'Migrace OK.' if ok else 'Migrace selhala (viz dialog).',
        xbmcgui.NOTIFICATION_INFO if ok else xbmcgui.NOTIFICATION_WARNING,
        3000,
    )
    xbmc.executebuiltin('Container.Refresh')
