"""Redis cache configuration and management.

This module handles Redis connections and caching operations.
"""

from typing import Optional, Any
from redis import Redis, ConnectionPool
import json

from src.config.settings import settings


# Redis Connection Pool
redis_pool = ConnectionPool.from_url(
    settings.REDIS_URL,
    max_connections=settings.REDIS_MAX_CONNECTIONS,
    decode_responses=True,
)

# Redis Client
redis_client = Redis(connection_pool=redis_pool)


def get_redis() -> Redis:
    """Get Redis client instance.
    
    Returns:
        Redis: Redis client
    """
    return redis_client


def cache_set(
    key: str,
    value: Any,
    ttl: Optional[int] = None
) -> bool:
    """Set cache value.
    
    Args:
        key: Cache key
        value: Value to cache
        ttl: Time to live in seconds
        
    Returns:
        bool: True if successful
    """
    try:
        serialized_value = json.dumps(value)
        if ttl:
            return redis_client.setex(key, ttl, serialized_value)
        return redis_client.set(key, serialized_value)
    except Exception:
        return False


def cache_get(key: str) -> Optional[Any]:
    """Get cache value.
    
    Args:
        key: Cache key
        
    Returns:
        Optional[Any]: Cached value or None
    """
    try:
        value = redis_client.get(key)
        if value:
            return json.loads(value)
        return None
    except Exception:
        return None


def cache_delete(key: str) -> bool:
    """Delete cache value.
    
    Args:
        key: Cache key
        
    Returns:
        bool: True if successful
    """
    try:
        return bool(redis_client.delete(key))
    except Exception:
        return False


def cache_clear_pattern(pattern: str) -> int:
    """Clear cache by pattern.
    
    Args:
        pattern: Key pattern (e.g., "user:*")
        
    Returns:
        int: Number of keys deleted
    """
    try:
        keys = redis_client.keys(pattern)
        if keys:
            return redis_client.delete(*keys)
        return 0
    except Exception:
        return 0

