"""
Lightweight Redis-backed Circuit Breaker for external API calls.
Prevents cascading failures when external services (Helius, OpenRouter, etc.) go down.
"""

import logging
import os
import time

import redis

logger = logging.getLogger(__name__)


def _get_redis() -> redis.Redis:
    return redis.Redis(
        host=os.getenv("REDIS_HOST", "localhost"),
        port=int(os.getenv("REDIS_PORT", "6379")),
        password=os.getenv("REDIS_PASSWORD", ""),
        decode_responses=True,
        socket_timeout=2,
    )


async def check_circuit(service: str) -> bool:
    """
    Returns True if circuit is OPEN (do not call the service).
    Returns False if CLOSED or HALF_OPEN (safe to call).
    """
    try:
        r = _get_redis()
        state = r.get(f"circuit:{service}:state")

        if state == "OPEN":
            opened_at = float(r.get(f"circuit:{service}:opened_at") or 0)
            if time.time() - opened_at > 60:  # 60 seconds cooldown
                r.set(f"circuit:{service}:state", "HALF_OPEN")
                logger.info(f"Circuit breaker for {service} moving to HALF_OPEN")
                return False
            return True  # Still OPEN, block the call

        return False  # CLOSED or HALF_OPEN
    except Exception as e:
        logger.error(f"Circuit breaker check failed for {service}: {e}")
        return False  # Fail open if Redis is down


async def record_success(service: str):
    try:
        r = _get_redis()
        r.set(f"circuit:{service}:state", "CLOSED")
        r.delete(f"circuit:{service}:failures")
    except Exception as e:
        logger.error(f"Circuit breaker success record failed for {service}: {e}")


async def record_failure(service: str):
    try:
        r = _get_redis()
        failures = r.incr(f"circuit:{service}:failures")
        if failures >= 5:
            r.set(f"circuit:{service}:state", "OPEN")
            r.set(f"circuit:{service}:opened_at", str(time.time()))
            logger.warning(f"Circuit breaker for {service} TRIPPED (OPEN) after 5 failures")
    except Exception as e:
        logger.error(f"Circuit breaker failure record failed for {service}: {e}")
