"""
Redis Keys:
- marine:catalog:full → lista dei dataset completo (TTL 1h)
- marine:catalog:search:{hash} → risultati ricerca (TTL 30min)
- marine:job:{session_id} → stato job download (TTL 48h)
"""

import json
import os
import logging
from typing import Any, Optional

import redis

logger = logging.getLogger(__name__)

# Configurazione Redis da variabili ambiente
REDIS_HOST = os.getenv("REDIS_HOST", "meb-redis")
REDIS_PORT = int(os.getenv("REDIS_PORT", "6379"))

# Pool di connessioni condiviso (thread-safe, riutilizzabile)
_pool: Optional[redis.ConnectionPool] = None
_client: Optional[redis.Redis] = None


def _get_client() -> Optional[redis.Redis]:
    """Restituisce il client Redis singleton con connection pool.
    Ritorna None se Redis non è raggiungibile."""
    global _pool, _client

    if _client is not None:
        return _client

    try:
        _pool = redis.ConnectionPool(
            host=REDIS_HOST,
            port=REDIS_PORT,
            # Decodifica automatica delle risposte in stringhe UTF-8
            decode_responses=True,
            # Massimo 5 connessioni nel pool (VPS 1-core, non serve di più)
            max_connections=5,
            # Timeout connessione e socket per evitare blocchi
            socket_connect_timeout=3,
            socket_timeout=3,
            # Riprova automaticamente se la connessione viene interrotta
            retry_on_timeout=True,
        )
        _client = redis.Redis(connection_pool=_pool)
        # Test connessione
        _client.ping()
        logger.info("[Redis] Connessione stabilita per il servizio Marine")
        return _client
    except Exception as e:
        logger.warning(f"[Redis] Non disponibile, la cache è disabilitata: {e}")
        _client = None
        return None


def cache_get(key: str) -> Optional[Any]:
    """Legge un valore dalla cache Redis.

    Args:
        key: Chiave Redis (es. 'marine:catalog:full')

    Returns:
        Il valore deserializzato da JSON, oppure None se non trovato o errore
    """
    try:
        client = _get_client()
        if client is None:
            return None

        data = client.get(key)
        if data is None:
            return None

        return json.loads(data)
    except Exception as e:
        logger.warning(f"[Redis] Errore lettura chiave '{key}': {e}")
        return None


def cache_set(key: str, value: Any, ttl: int = 3600) -> bool:
    """Scrive un valore nella cache Redis con TTL.

    Args:
        key: Chiave Redis
        value: Valore da serializzare in JSON
        ttl: Tempo di vita in secondi (default: 1 ora)

    Returns:
        True se scritto con successo, False altrimenti
    """
    try:
        client = _get_client()
        if client is None:
            return False

        serialized = json.dumps(value)
        client.setex(key, ttl, serialized)
        return True
    except Exception as e:
        logger.warning(f"[Redis] Errore scrittura chiave '{key}': {e}")
        return False


def cache_delete(key: str) -> bool:
    """Elimina una chiave dalla cache Redis.

    Args:
        key: Chiave Redis da eliminare

    Returns:
        True se eliminata, False altrimenti
    """
    try:
        client = _get_client()
        if client is None:
            return False

        client.delete(key)
        return True
    except Exception as e:
        logger.warning(f"[Redis] Errore eliminazione chiave '{key}': {e}")
        return False
