# -*- coding: utf-8 -*-
import xbmcaddon
import xbmcvfs
import time
import os
import re
from resources.lib.database.metadata_db import db
from resources.lib.utils.log_utils import get_logger

log = get_logger()
ADDON_ID = 'plugin.video.mmirousek_v3'

_last_scan_time = 0


def _parse_season_dir_name(dirname: str):
    from resources.lib.down.offline_cache_utils import parse_season_dir_name
    return parse_season_dir_name(dirname)

# =============================================================================
# [DEBUG-SCAN] ZAČÁTEK – DOČASNÉ PODROBNÉ LOGOVÁNÍ SCANNERU
# Po odladění SMAŽ všechny bloky označené "[DEBUG-SCAN]" a vrať funkci
# run_offline_scan() do původní tiché podoby.
# =============================================================================
_DEBUG_SCAN = False  # [DEBUG-SCAN] master vypínač – nastav False pro utišení

def _dbg(msg: str):
    """[DEBUG-SCAN] Logovací helper – píše na INFO úroveň, aby bylo vidět
    i bez zapnutého debug logu v Kodi. Prefix [OfflineScanner][DBG] je
    snadno grepovatelný: `grep "OfflineScanner\\[DBG\\]" kodi.log`.
    """
    if _DEBUG_SCAN:
        log.info(f"[OfflineScanner][DBG] {msg}")
# =============================================================================
# [DEBUG-SCAN] KONEC hlavičky – hlavní tělo logování viz níže uvnitř funkce.
# =============================================================================


def run_offline_scan(force=False):
    global _last_scan_time
    now = time.time()

    # Skenujeme každých 5 minut nebo pokud je explicitně zavoláno (např. po smazání souboru)
    if not force and (now - _last_scan_time < 3600):
        # --- [DEBUG-SCAN] ---
        _dbg(f"Skip běhu – throttle ({int(now - _last_scan_time)}s od posledního scanu, force={force})")
        # --- [DEBUG-SCAN] konec ---
        return

    # --- [DEBUG-SCAN] ---
    _t_start = time.time()
    _dbg(f"=== START scan (force={force}, last_scan_time={_last_scan_time}) ===")
    _stats = {
        'dirs_total': 0,
        'dirs_skipped_listdir_err': 0,
        'season_dirs_total': 0,
        'season_dirs_skipped_regex': 0,
        'season_dirs_skipped_listdir_err': 0,
        'files_total': 0,
        'files_skipped_ext': 0,
        'files_skipped_regex': 0,
        'files_matched': 0,
        'stat_errors': 0,
        'tmdb_mapped': 0,
        'tmdb_not_mapped': 0,
        'series_with_items': 0,
        'series_without_items': 0,
        'removed_from_cache': 0,
    }
    # --- [DEBUG-SCAN] konec ---

    try:
        from resources.lib.down.offline_cache_utils import (
            resolve_dfolder_path,
            resolve_offline_cache_key_for_disk_folder,
            build_disk_folder_to_storage_key_index,
            merge_offline_scan_items,
        )
        addon = xbmcaddon.Addon(ADDON_ID)
        dfolder = resolve_dfolder_path(addon)
        if not dfolder:
            # --- [DEBUG-SCAN] ---
            _dbg("ABORT – nastavení 'dfolder' je prázdné")
            # --- [DEBUG-SCAN] konec ---
            return

        if not xbmcvfs.exists(dfolder):
            # --- [DEBUG-SCAN] ---
            _dbg(f"ABORT – dfolder neexistuje: '{dfolder}'")
            # --- [DEBUG-SCAN] konec ---
            return

        log.info(f"[OfflineScanner] Scan dfolder: {dfolder}")
        log.debug("[OfflineScanner] Spouštím scan offline souborů na pozadí")
        # --- [DEBUG-SCAN] ---
        _dbg(f"dfolder='{dfolder}'")
        # --- [DEBUG-SCAN] konec ---
        _last_scan_time = now

        folder_index = build_disk_folder_to_storage_key_index()
        cache_data = {}
        dirs, files = xbmcvfs.listdir(dfolder)

        # --- [DEBUG-SCAN] ---
        _stats['dirs_total'] = len(dirs)
        _dbg(f"Root listdir: {len(dirs)} podsložek, {len(files)} souborů v kořeni (ignorovány)")
        if dirs:
            _dbg(f"Nalezené složky seriálů: {dirs}")
        # --- [DEBUG-SCAN] konec ---

        existing_cache = db.get_offline_cache_all()

        if not dirs and existing_cache:
            log.warning(
                "[OfflineScanner] dfolder neobsahuje žádné podsložky – "
                "offline_cache se nemaže (ochrana před falešně prázdným scanem)"
            )
            # --- [DEBUG-SCAN] ---
            _dbg("ABORT – 0 podsložek, existující cache zachována")
            # --- [DEBUG-SCAN] konec ---
            return

        for d in dirs:
            # --- [DEBUG-SCAN] ---
            _dbg(f"--- Zpracovávám složku seriálu: '{d}'")
            # --- [DEBUG-SCAN] konec ---

            series_name = resolve_offline_cache_key_for_disk_folder(d, folder_index)
            if re.match(r'^tmdb_\d+$', d, re.IGNORECASE):
                if series_name != d:
                    # --- [DEBUG-SCAN] ---
                    _stats['tmdb_mapped'] += 1
                    _dbg(f"    tmdb mapping OK: '{d}' -> klíč '{series_name}'")
                    # --- [DEBUG-SCAN] konec ---
                elif d not in folder_index:
                    # --- [DEBUG-SCAN] ---
                    _stats['tmdb_not_mapped'] += 1
                    _dbg(f"    tmdb mapping FAIL: '{d}' – seriál není v series_data")
                    # --- [DEBUG-SCAN] konec ---
            # --- [DEBUG-SCAN] ---
            else:
                mapped = series_name if series_name != d else None
                if mapped:
                    _dbg(f"    složka '{d}' mapována na storage klíč '{series_name}'")
                else:
                    _dbg(f"    klíč pro offline_cache = '{series_name}'")
            # --- [DEBUG-SCAN] konec ---

            # U síťových pevných disků SMB je kompatibilnější skládat cestu manuálně nebo přes os.path.join a pak sjednotit lomítka
            series_path = os.path.join(dfolder, d).replace('\\', '/')
            if not series_path.endswith('/'):
                series_path += '/'

            try:
                season_dirs, _ = xbmcvfs.listdir(series_path)
            except Exception as _e_listdir:
                # --- [DEBUG-SCAN] ---
                _stats['dirs_skipped_listdir_err'] += 1
                _dbg(f"    SKIP – listdir selhal na '{series_path}': {_e_listdir}")
                # --- [DEBUG-SCAN] konec ---
                continue

            # --- [DEBUG-SCAN] ---
            _dbg(f"    Podsložky v seriálu: {season_dirs}")
            # --- [DEBUG-SCAN] konec ---

            items = []

            for sd in season_dirs:
                # --- [DEBUG-SCAN] ---
                _stats['season_dirs_total'] += 1
                # --- [DEBUG-SCAN] konec ---
                season_num = _parse_season_dir_name(sd)
                if season_num is None:
                    # --- [DEBUG-SCAN] ---
                    _stats['season_dirs_skipped_regex'] += 1
                    _dbg(f"    SKIP sezóna '{sd}' – neodpovídá regexu sezóny")
                    # --- [DEBUG-SCAN] konec ---
                    continue

                season_path = os.path.join(series_path, sd).replace('\\', '/')
                if not season_path.endswith('/'):
                    season_path += '/'

                try:
                    _, ep_files = xbmcvfs.listdir(season_path)
                except Exception as _e_listdir2:
                    # --- [DEBUG-SCAN] ---
                    _stats['season_dirs_skipped_listdir_err'] += 1
                    _dbg(f"    SKIP sezóna '{sd}' – listdir selhal na '{season_path}': {_e_listdir2}")
                    # --- [DEBUG-SCAN] konec ---
                    continue

                # --- [DEBUG-SCAN] ---
                _dbg(f"    Sezóna '{sd}' (num={season_num}): {len(ep_files)} souborů")
                _matched_in_season = 0
                # --- [DEBUG-SCAN] konec ---

                for ef in ep_files:
                    # --- [DEBUG-SCAN] ---
                    _stats['files_total'] += 1
                    # --- [DEBUG-SCAN] konec ---
                    if ef.lower().endswith(('.mp4', '.mkv', '.avi', '.ts')):
                        # Očekáváme "Název S01E03.mp4" nebo podobný formát
                        ep_match = re.search(r'(?i)S\d+E(\d+)', ef)
                        if ep_match:
                            ep_num = int(ep_match.group(1))
                            ep_path = os.path.join(season_path, ef).replace('\\', '/')

                            try:
                                st = xbmcvfs.Stat(ep_path)
                                size = st.st_size() if st else 0
                            except Exception as _e_stat:
                                size = 0
                                # --- [DEBUG-SCAN] ---
                                _stats['stat_errors'] += 1
                                _dbg(f"        STAT FAIL '{ef}': {_e_stat}")
                                # --- [DEBUG-SCAN] konec ---

                            items.append({
                                'season': season_num,
                                'episode': ep_num,
                                'path': ep_path,
                                'size': size
                            })
                            # --- [DEBUG-SCAN] ---
                            _stats['files_matched'] += 1
                            _matched_in_season += 1
                            _dbg(f"        MATCH S{season_num:02d}E{ep_num:02d} – '{ef}' ({size} B)")
                            # --- [DEBUG-SCAN] konec ---
                        else:
                            # --- [DEBUG-SCAN] ---
                            _stats['files_skipped_regex'] += 1
                            _dbg(f"        SKIP soubor '{ef}' – neobsahuje pattern SxxExx")
                            # --- [DEBUG-SCAN] konec ---
                    else:
                        # --- [DEBUG-SCAN] ---
                        _stats['files_skipped_ext'] += 1
                        _dbg(f"        SKIP soubor '{ef}' – nepodporovaná přípona (povoleno: mp4/mkv/avi/ts)")
                        # --- [DEBUG-SCAN] konec ---

                # --- [DEBUG-SCAN] ---
                _dbg(f"    Sezóna '{sd}' dokončena – nalezeno {_matched_in_season} epizod")
                # --- [DEBUG-SCAN] konec ---

            if items:
                prior = cache_data.get(series_name, [])
                cache_data[series_name] = merge_offline_scan_items(prior, items)
            # --- [DEBUG-SCAN] ---
            merged_items = cache_data.get(series_name, [])
            if merged_items:
                _stats['series_with_items'] += 1
                _seasons_set = sorted({it['season'] for it in merged_items})
                _dbg(f"    Seriál '{d}' -> klíč '{series_name}': {len(merged_items)} epizod, sezóny {_seasons_set}")
            else:
                _stats['series_without_items'] += 1
                _dbg(f"    Seriál '{d}' -> klíč '{series_name}': ŽÁDNÉ epizody nenalezeny")
            # --- [DEBUG-SCAN] konec ---

        # Uložíme aktualizovaná data seriál po seriálu
        active_keys_with_items = set()
        for s_name, s_items in cache_data.items():
            if s_items:
                db.save_offline_cache_items(s_name, s_items)
                active_keys_with_items.add(s_name)
                # --- [DEBUG-SCAN] ---
                _dbg(f"SAVE offline_cache: klíč '{s_name}' = {len(s_items)} epizod")
                # --- [DEBUG-SCAN] konec ---

        if not active_keys_with_items and existing_cache and _stats['dirs_total'] > 0:
            log.warning(
                "[OfflineScanner] Nalezeny složky seriálů, ale 0 epizod – "
                "offline_cache se nemaže (zkontrolujte strukturu Sezona N / SxxExx)"
            )
            # --- [DEBUG-SCAN] ---
            _dbg("ABORT save/cleanup – 0 epizod při nenulovém počtu složek")
            # --- [DEBUG-SCAN] konec ---
            return

        # Odstraníme z cache seriály, které už na disku nejsou
        for existing_series in existing_cache.keys():
            if existing_series not in active_keys_with_items:
                db.clear_offline_cache_for_series(existing_series)
                # --- [DEBUG-SCAN] ---
                _stats['removed_from_cache'] += 1
                _dbg(f"REMOVE z offline_cache: klíč '{existing_series}' už není na disku")
                # --- [DEBUG-SCAN] konec ---

        log.info(
            f"[OfflineScanner] Dokončen scan: {len(active_keys_with_items)} seriálů, "
            f"{sum(len(cache_data[k]) for k in active_keys_with_items)} epizod"
        )
        # --- [DEBUG-SCAN] ---
        _dbg(
            "=== SUMMARY === "
            f"trvání={time.time() - _t_start:.2f}s | "
            f"složek={_stats['dirs_total']} "
            f"(listdir_err={_stats['dirs_skipped_listdir_err']}) | "
            f"tmdb mapped={_stats['tmdb_mapped']}/not={_stats['tmdb_not_mapped']} | "
            f"sezóny total={_stats['season_dirs_total']} "
            f"(skip regex={_stats['season_dirs_skipped_regex']}, listdir_err={_stats['season_dirs_skipped_listdir_err']}) | "
            f"soubory total={_stats['files_total']} "
            f"(match={_stats['files_matched']}, skip ext={_stats['files_skipped_ext']}, skip regex={_stats['files_skipped_regex']}) | "
            f"stat_err={_stats['stat_errors']} | "
            f"seriály s_itemy={_stats['series_with_items']}/prázdné={_stats['series_without_items']} | "
            f"odstraněno z cache={_stats['removed_from_cache']}"
        )
        _dbg("=== END scan ===")
        # --- [DEBUG-SCAN] konec ---

    except Exception as e:
        log.error(f"[OfflineScanner] Chyba při skenování offline souborů: {e}")
        # --- [DEBUG-SCAN] ---
        import traceback
        _dbg(f"EXCEPTION: {e}\n{traceback.format_exc()}")
        # --- [DEBUG-SCAN] konec ---
