import os
import json
import time
import hashlib
import xbmcaddon
import xbmc

# Cesta k souboru s cache v profilu doplňku
ADDON = xbmcaddon.Addon()
PROFILE = ADDON.getAddonInfo('profile')
CACHE_FILE = os.path.join(PROFILE, 'tmdb_cache.json')

# DEBUG: Log cache path
xbmc.log(f"[WCS CACHE DEBUG] Cache file path: {CACHE_FILE}", xbmc.LOGINFO)
xbmc.log(f"[WCS CACHE DEBUG] Profile directory exists: {os.path.exists(PROFILE)}", xbmc.LOGINFO)

# Načte celou cache ze souboru
def _load_cache():
    if not os.path.exists(CACHE_FILE):
        xbmc.log(f"[WCS CACHE DEBUG] Cache soubor neexistuje: {CACHE_FILE}", xbmc.LOGINFO)
        return {}
    try:
        with open(CACHE_FILE, 'r', encoding='utf-8') as f:
            cache = json.load(f)
        xbmc.log(f"[WCS CACHE DEBUG] Cache načten: {len(cache)} klíčů", xbmc.LOGINFO)
        return cache
    except Exception as e:
        xbmc.log(f"[WCS CACHE DEBUG] Chyba při načítání cache: {e}", xbmc.LOGERROR)
        return {}

# Uloží celou cache do souboru
def _save_cache(cache):
    try:
        # Ujisti se, že existuje adresář
        os.makedirs(os.path.dirname(CACHE_FILE), exist_ok=True)
        
        with open(CACHE_FILE, 'w', encoding='utf-8') as f:
            json.dump(cache, f, ensure_ascii=False)
        xbmc.log(f"[WCS CACHE DEBUG] Cache uložen: {len(cache)} klíčů do {CACHE_FILE}", xbmc.LOGINFO)
    except Exception as e:
        xbmc.log(f"[WCS CACHE DEBUG] CHYBA při ukládání cache: {e}", xbmc.LOGERROR)

# Vytvoří unikátní klíč pro cache na základě endpointu a parametrů
# Parametry serializujeme a hashujeme pro univerzálnost
def _make_key(endpoint, params):
    params_str = json.dumps(params, sort_keys=True, ensure_ascii=False)
    raw_key = f'{endpoint}|{params_str}'
    return hashlib.sha256(raw_key.encode('utf-8')).hexdigest()

# Získá data z cache, pokud existují a nejsou expirovaná
# expire_seconds: doba platnosti v sekundách
# Pokud není v cache nebo je expirováno, vrací None
# Pro novinky/trendy doporučujeme kratší dobu (např. 1-6h), pro kolekce/metadata delší (např. 24-168h)
def get_from_cache(endpoint, params, expire_seconds=86400):
    cache = _load_cache()
    key = _make_key(endpoint, params)
    entry = cache.get(key)
    if not entry:
        return None
    if time.time() - entry['time'] > expire_seconds:
        return None
    return entry['data']

# Uloží data do cache
# expire_seconds zde slouží jen pro informaci, není ukládáno
# (expirace se řeší při čtení)
def set_to_cache(endpoint, params, data):
    cache = _load_cache()
    key = _make_key(endpoint, params)
    cache[key] = {'time': time.time(), 'data': data}
    _save_cache(cache)

# Hlavní API: pokusí se vrátit data z cache, jinak zavolá fetch_fn a uloží výsledek
# fetch_fn: funkce bez argumentů, která vrací data (např. volání requests.get(...).json())
# expire_seconds: viz výše
# Příklad použití viz níže
#
# Doporučení: Pro novinky/trendy použijte expire_seconds=3600 (1h), pro kolekce/metadata 604800 (7 dní)
def get_or_fetch(endpoint, params, fetch_fn, expire_seconds=86400):
    data = get_from_cache(endpoint, params, expire_seconds)
    if data is not None:
        return data
    data = fetch_fn()
    if data is not None:
        set_to_cache(endpoint, params, data)
    return data

# Příklad použití v kódu:
# from wcs import tmdb_cache
# def fetch_collection(cid):
#     endpoint = f'/collection/{cid}'
#     params = {'language': 'cs-CZ'}
#     def fetch():
#         ... (requests.get ...)
#     data = tmdb_cache.get_or_fetch(endpoint, params, fetch, expire_seconds=604800)
#     ... 