# -*- coding: utf-8 -*-
"""Sdílené utility pro offline_cache a dfolder – bez závislosti na SeriesManager."""

import json
import re

import xbmcaddon
import xbmcvfs

from resources.lib.database.metadata_db import db as _metadata_db
from resources.lib.utils.log_utils import get_logger
from resources.lib.utils.ui_utils import clean_filename

log = get_logger()

ADDON_ID = 'plugin.video.mmirousek_v3'

_RE_STORAGE_TMDB = re.compile(r"^tmdb_\d+$", re.IGNORECASE)


def resolve_folder_display_name(series_name: str, data: dict) -> str:
    """
    Název složky na disku: preferuj lidský titul z DB/TMDb/search query,
    storage key `tmdb_<id>` používej jen jako poslední fallback.
    """
    if not isinstance(data, dict):
        data = {}

    def _usable_title(value) -> str:
        value = (value or "").strip()
        return value if value and not _RE_STORAGE_TMDB.match(value) else ""

    title = _usable_title(data.get("name"))
    if title:
        return title

    tmdb = data.get("tmdb") or {}
    if isinstance(tmdb, dict):
        for key in ("title", "name", "original_title", "original_name"):
            title = _usable_title(tmdb.get(key))
            if title:
                return title

    title = _usable_title(data.get("search_query_name"))
    if title:
        return title

    aliases = data.get("aliases") or []
    if isinstance(aliases, list):
        for alias in aliases:
            title = _usable_title(alias)
            if title:
                return title

    fallback = (series_name or "").strip()
    if _RE_STORAGE_TMDB.match(fallback):
        log.debug(f"[offline] Používám storage key jako fallback názvu složky: {fallback}")
    return fallback


def sync_active_dfolder_setting(addon=None):
    """Zkopíruje aktivní slot (dfolder_1/2/3) do nastavení dfolder."""
    try:
        addon = addon or xbmcaddon.Addon(ADDON_ID)
        raw_slot = addon.getSetting('dfolder_slot') or '0'
        slot_idx = 0
        if raw_slot == 'Složka 1':
            slot_idx = 0
        elif raw_slot == 'Složka 2':
            slot_idx = 1
        elif raw_slot == 'Složka 3':
            slot_idx = 2
        else:
            try:
                slot_idx = int(raw_slot)
            except ValueError:
                slot_idx = 0
        slot_path = addon.getSetting(f'dfolder_{slot_idx + 1}') or ''
        if slot_path and slot_path != (addon.getSetting('dfolder') or ''):
            addon.setSetting('dfolder', slot_path)
    except Exception as e:
        log.debug(f"[offline] sync_active_dfolder_setting: {e}")


def resolve_dfolder_path(addon=None):
    """Vrátí přeloženou VFS cestu aktivní offline složky (s trailing /)."""
    addon = addon or xbmcaddon.Addon(ADDON_ID)
    sync_active_dfolder_setting(addon)
    raw = (addon.getSetting('dfolder') or '').strip()
    if not raw:
        return ''
    try:
        real = xbmcvfs.translatePath(raw) or raw
    except Exception:
        real = raw
    if not real:
        return ''
    if not xbmcvfs.exists(real) and raw != real and xbmcvfs.exists(raw):
        real = raw
    real = real.replace('\\', '/')
    if not real.endswith('/'):
        real += '/'
    return real


def offline_cache_lookup_keys(series_name: str, series_data: dict = None) -> list:
    """Všechny možné klíče offline_cache pro seriál (storage key + název složky na disku)."""
    keys = []

    def _add(value):
        key = clean_filename(value) if value else ''
        if key and key not in keys:
            keys.append(key)

    _add(series_name)
    if isinstance(series_data, dict):
        _add(resolve_folder_display_name(series_name, series_data))
        _add(series_data.get('name'))
    return keys


def build_disk_folder_to_storage_key_index() -> dict:
    """Mapa clean_filename(název_složky_na_disku) -> clean_filename(storage_key)."""
    index = {}
    if not _metadata_db.conn:
        return index
    try:
        cur = _metadata_db.conn.execute("SELECT series_name, json_data FROM series_data")
        for storage_key, json_blob in cur.fetchall():
            try:
                data = json.loads(json_blob or '{}')
            except Exception:
                data = {}
            sk = clean_filename(storage_key)
            if sk:
                index[sk] = sk
            for candidate in (
                resolve_folder_display_name(storage_key, data),
                (data.get('name') or ''),
            ):
                folder_key = clean_filename(candidate)
                if folder_key:
                    index[folder_key] = sk or folder_key
    except Exception as e:
        log.warning(f"[offline] Nelze sestavit index složek seriálů: {e}")
    return index


def resolve_offline_cache_key_for_disk_folder(folder_name: str, folder_index: dict = None) -> str:
    """Určí primární klíč offline_cache pro složku nalezenou na disku."""
    folder_key = clean_filename(folder_name)
    if not folder_key:
        return ''
    if _RE_STORAGE_TMDB.match(folder_name):
        return folder_key
    if folder_index is None:
        folder_index = build_disk_folder_to_storage_key_index()
    return folder_index.get(folder_key, folder_key)


def get_merged_offline_cache(series_name: str, series_data: dict = None) -> list:
    """Sloučí offline_cache záznamy ze všech aliasů seriálu (bez duplicit S/E)."""
    merged = []
    seen = set()
    for key in offline_cache_lookup_keys(series_name, series_data):
        for item in _metadata_db.get_offline_cache_for_series(key) or []:
            try:
                sig = (int(item.get('season', -1)), int(item.get('episode', -1)))
            except (TypeError, ValueError):
                continue
            if sig in seen:
                continue
            seen.add(sig)
            merged.append(item)
    return merged
