# services/cache_service.py

import redis
import logging
import json
from typing import Optional, Any
from config.settings import Config

logger = logging.getLogger(__name__)

class CacheService:
    """Service for handling Redis caching."""
    def __init__(self, host: str = Config.REDIS_HOST, port: int = Config.REDIS_PORT, db: int = 0):
        try:
            self.client = redis.Redis(host=host, port=port, db=db, decode_responses=True)
            self.client.ping()
            logger.info("Successfully connected to Redis at %s:%s", host, port)
        except redis.exceptions.ConnectionError as e:
            logger.error("Could not connect to Redis: %s. Caching will be disabled.", e)
            self.client = None

    def get(self, key: str) -> Optional[Any]:
        """Get a value from the cache."""
        if not self.client:
            return None
        try:
            value = self.client.get(key)
            return json.loads(value) if value else None
        except (redis.exceptions.RedisError, json.JSONDecodeError) as e:
            logger.error("Redis GET error for key '%s': %s", key, e)
            return None

    def set(self, key: str, value: Any, expiry_seconds: int = 3600):
        """Set a value in the cache with an expiry."""
        if not self.client:
            return
        try:
            self.client.setex(key, expiry_seconds, json.dumps(value))
        except redis.exceptions.RedisError as e:
            logger.error("Redis SET error for key '%s': %s", key, e)

    def xadd(self, stream: str, data: dict):
        """Append entry to a Redis stream (non‑blocking in prod)."""
        if self.client:
            self.client.xadd(stream, data)

    def xrange(self, stream: str, start: str = "-", end: str = "+"):
        """Read all entries in a Redis stream."""
        if self.client:
            return self.client.xrange(stream, start, end)
        return []