"""Redis-Client für TimeMaster (sync + async, für Kiosk-Nonce-Cache, Sessions, Locks)."""
from __future__ import annotations

import logging
from typing import Optional

log = logging.getLogger(__name__)

_redis_client = None
_async_redis_client = None


def get_redis_client():
    """Gibt den (sync) Redis-Client zurück oder None wenn nicht konfiguriert/erreichbar."""
    global _redis_client
    if _redis_client is not None:
        return _redis_client
    try:
        import redis as redis_lib
        from app.core.config import settings
        url = getattr(settings, "redis_url", "redis://localhost:6379/0")
        _redis_client = redis_lib.from_url(url, decode_responses=True, socket_connect_timeout=2)
        # Verbindung testen
        _redis_client.ping()
        log.info("Redis-Verbindung hergestellt: %s", url)
        return _redis_client
    except Exception as exc:
        log.warning("Redis nicht verfügbar: %s", exc)
        return None


def get_async_redis():
    """Gepoolter async Redis-Client (eine Verbindungspool-Instanz pro Prozess).

    Nicht pro Request neu verbinden/schließen (frühere Falle in totp_login und
    kiosk_security._check_and_set_nonce) – der Pool verwaltet Connections selbst.
    Verbindungsfehler zeigen sich erst beim ersten Call (kein Ping hier), Aufrufer
    müssen weiterhin except behandeln (Nonce-Fallback, TOTP-Lockout).
    """
    global _async_redis_client
    if _async_redis_client is None:
        import redis.asyncio as aioredis
        from app.core.config import settings
        url = getattr(settings, "redis_url", "redis://localhost:6379/0")
        _async_redis_client = aioredis.from_url(url, decode_responses=True)
    return _async_redis_client


async def close_async_redis() -> None:
    """Pool sauber schließen – im FastAPI-Lifespan-Shutdown aufrufen."""
    global _async_redis_client
    if _async_redis_client is not None:
        await _async_redis_client.aclose()
        _async_redis_client = None
