# -*- coding: utf-8 -*-
"""
Klient Streaming Availability API (RapidAPI).
Dokumentace: https://docs.movieofthenight.com/resource/changes

Poznámka: parametr output_language podle OpenAPI podporuje jen en, es, tr, fr (ne „cs“) —
neplatná hodnota končí HTTP 400.
"""
from __future__ import annotations

import json
from typing import Any, Dict, List, Optional, Tuple

import requests

from resources.lib.trakt.trakt_service import FileCache
from resources.lib.utils.log_utils import get_logger

log = get_logger()

ADDON_ID = "plugin.video.mmirousek_v3"

RAPIDAPI_HOST = "streaming-availability.p.rapidapi.com"
BASE_URL = "https://{0}".format(RAPIDAPI_HOST)

CACHE_TTL_SEC = 86400  # 24 h

_PLACEHOLDER_KEYS = frozenset(("", "YOUR_API_KEY_HERE"))


def get_rapidapi_key() -> str:
    """Načte X-RapidAPI-Key z nastavení doplňku (settings.xml → rapidapi_streaming_availability_key)."""
    try:
        import xbmcaddon

        return (xbmcaddon.Addon(ADDON_ID).getSetting("rapidapi_streaming_availability_key") or "").strip()
    except Exception as e:
        log.warning(f"[StreamingAvail] nelze načíst nastavení klíče: {e}")
        return ""

# Výchozí služby pro CZ (ID katalogů dle API). HBO v EU často jako „max“, ne „hbo“.
DEFAULT_CATALOGS: List[str] = ["netflix", "hbo", "disney", "apple", "prime"]

DEFAULT_COUNTRY = "cz"

_cache_singleton: Optional[FileCache] = None


def _cache() -> FileCache:
    global _cache_singleton
    if _cache_singleton is None:
        _cache_singleton = FileCache(namespace="streaming_availability")
    return _cache_singleton


def _cache_key(params: Dict[str, Any]) -> str:
    return "GET/changes\n" + json.dumps(params, sort_keys=True, ensure_ascii=False)


def is_api_key_configured() -> bool:
    k = get_rapidapi_key()
    return bool(k) and k not in _PLACEHOLDER_KEYS


def fetch_changes(
    country: str = DEFAULT_COUNTRY,
    change_type: str = "new",
    item_type: str = "show",
    show_type: str = "movie",
    catalogs: Optional[List[str]] = None,
    cursor: Optional[str] = None,
    output_language: str = "en",
) -> Tuple[Optional[Dict[str, Any]], Optional[str]]:
    """
    Vrátí (data, None) při úspěchu; data obsahuje changes, shows, hasMore, nextCursor.
    Při chybě (None, kód): 'missing_api_key' | 'unauthorized' | 'rate_limit' | text výjimky.
    """
    api_key = get_rapidapi_key()
    if not api_key or api_key in _PLACEHOLDER_KEYS:
        log.warning("[StreamingAvail] chybí platný RapidAPI klíč v nastavení doplňku")
        return None, "missing_api_key"

    cats = catalogs if catalogs is not None else DEFAULT_CATALOGS
    params: Dict[str, Any] = {
        "country": (country or DEFAULT_COUNTRY).lower(),
        "change_type": change_type,
        "item_type": item_type,
        "show_type": show_type,
        "catalogs": ",".join(cats),
        "output_language": output_language,
    }
    if cursor:
        params["cursor"] = cursor

    key = _cache_key(params)
    cached = _cache().get(key)
    if cached is not None:
        payload = cached.get("data")
        log.info(f"[StreamingAvail] cache HIT {key[:72]}...")
        return payload, None

    # RapidAPI dokumentace používá malá jména hlaviček; get_logger() neprovádí % formátování druhého argumentu.
    headers = {
        "x-rapidapi-key": api_key,
        "x-rapidapi-host": RAPIDAPI_HOST,
    }
    url = BASE_URL + "/changes"
    try:
        r = requests.get(url, headers=headers, params=params, timeout=25)
        if r.status_code == 401:
            log.error("[StreamingAvail] 401 unauthorized")
            return None, "unauthorized"
        if r.status_code == 429:
            log.error("[StreamingAvail] 429 rate limit")
            return None, "rate_limit"
        if r.status_code >= 400:
            snippet = (r.text or "")[:800]
            log.error(f"[StreamingAvail] HTTP {r.status_code} body: {snippet}")
            return None, f"http_{r.status_code}"
        data = r.json()
    except requests.RequestException as e:
        log.error(f"[StreamingAvail] HTTP chyba: {e}")
        return None, str(e)
    except Exception as e:
        log.error(f"[StreamingAvail] parse chyba: {e}")
        return None, str(e)

    _cache().set(key, data, hdr={}, ttl_sec=CACHE_TTL_SEC)
    n = len(data.get("changes") or [])
    log.info(f"[StreamingAvail] cache MISS uloženo 24h, changes={n}")
    return data, None
