# -*- 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

# =============================================================================
# [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:
        addon = xbmcaddon.Addon(ADDON_ID)
        dfolder = addon.getSetting('dfolder')
        if not dfolder:
            # --- [DEBUG-SCAN] ---
            _dbg("ABORT – nastavení 'dfolder' je prázdné")
            # --- [DEBUG-SCAN] konec ---
            return

        # Zajištění lomítka pro xbmcvfs
        if not dfolder.endswith('/') and not dfolder.endswith('\\'):
            dfolder += '/'

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

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

        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 ---

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

            # Pokud je složka ve formátu tmdb_XXXX, dohledej display_name z DB
            series_name = d
            if re.match(r'^tmdb_\d+$', d):
                try:
                    from resources.lib.database.metadata_db import db as _db_ref
                    row = _db_ref.conn.execute(
                        "SELECT json_data FROM series_data WHERE series_name = ?", (d,)
                    ).fetchone() if _db_ref.conn else None
                    if row:
                        import json as _json
                        _data = _json.loads(row[0])
                        _nm = (_data.get('name') or '').strip()
                        if _nm:
                            from resources.lib.utils.ui_utils import clean_filename as _cf
                            series_name = _cf(_nm)
                            log.debug(f"[OfflineScanner] Složka '{d}' mapována na display_name klíč: '{series_name}'")
                            # --- [DEBUG-SCAN] ---
                            _stats['tmdb_mapped'] += 1
                            _dbg(f"    tmdb mapping OK: '{d}' -> klíč '{series_name}' (z DB name='{_nm}')")
                            # --- [DEBUG-SCAN] konec ---
                        else:
                            # --- [DEBUG-SCAN] ---
                            _stats['tmdb_not_mapped'] += 1
                            _dbg(f"    tmdb mapping FAIL: '{d}' – v series_data chybí 'name'")
                            # --- [DEBUG-SCAN] konec ---
                    else:
                        # --- [DEBUG-SCAN] ---
                        _stats['tmdb_not_mapped'] += 1
                        _dbg(f"    tmdb mapping FAIL: '{d}' – žádný řádek v series_data (seriál nebyl otevřen)")
                        # --- [DEBUG-SCAN] konec ---
                except Exception as _e:
                    log.warning(f"[OfflineScanner] Nelze mapovat tmdb_ složku '{d}': {_e}")
                    # --- [DEBUG-SCAN] ---
                    _stats['tmdb_not_mapped'] += 1
                    # --- [DEBUG-SCAN] konec ---
            # --- [DEBUG-SCAN] ---
            else:
                _dbg(f"    klíč pro offline_cache = '{series_name}' (bez tmdb mapování)")
            # --- [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 ---
                # Očekáváme např. "Sezona 1" (nebo Season 1)
                season_match = re.search(r'(?i)(?:Season|Sezona)\s+(\d+)', sd)
                if not season_match:
                    # --- [DEBUG-SCAN] ---
                    _stats['season_dirs_skipped_regex'] += 1
                    _dbg(f"    SKIP sezóna '{sd}' – neodpovídá regexu 'Sezona N' / 'Season N'")
                    # --- [DEBUG-SCAN] konec ---
                    continue
                season_num = int(season_match.group(1))

                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 ---

            cache_data[series_name] = items
            # --- [DEBUG-SCAN] ---
            if items:
                _stats['series_with_items'] += 1
                _seasons_set = sorted({it['season'] for it in items})
                _dbg(f"    Seriál '{d}' -> klíč '{series_name}': {len(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 ---

        # Zjistíme existující záznamy pro odstranění smazaných seriálů z cache
        existing_cache = db.get_offline_cache_all()
        for existing_series in existing_cache.keys():
            if existing_series not in cache_data:
                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 ---

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

        log.info(f"[OfflineScanner] Dokončen scan offline souborů pro {len(cache_data)} seriálů")
        # --- [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 ---
