"""
LLM-specific rate limit error detection.
"""

from loguru import logger


def is_llm_rate_limit_error(error: Exception) -> bool:
    """
    Detect if an error is a rate limit error from an LLM provider.

    Args:
        error: The exception to check

    Returns:
        True if this is a rate limit error, False otherwise
    """
    error_str = str(error).lower()
    error_type = type(error).__name__.lower()

    # Check for explicit HTTP 429 status codes
    if hasattr(error, "response") and hasattr(error.response, "status_code"):
        if error.response.status_code == 429:
            logger.debug(f"Detected HTTP 429 rate limit error: {error}")
            return True

    # Check for common rate limit error messages
    rate_limit_indicators = [
        "rate limit",
        "rate_limit",
        "ratelimit",
        "too many requests",
        "quota exceeded",
        "quota has been exhausted",
        "resource has been exhausted",
        "429",
        "threshold",
        "try again later",
        "slow down",
    ]

    if any(indicator in error_str for indicator in rate_limit_indicators):
        logger.debug(f"Detected rate limit error from message: {error}")
        return True

    # Check for specific provider error types
    if "ratelimiterror" in error_type or "quotaexceeded" in error_type:
        logger.debug(f"Detected rate limit error from type: {type(error)}")
        return True

    # Check for OpenAI specific rate limit errors
    if hasattr(error, "__class__") and error.__class__.__module__ == "openai":
        if error_type in ["ratelimiterror", "apierror"] and "429" in error_str:
            logger.debug(f"Detected OpenAI rate limit error: {error}")
            return True

    # Check for Anthropic specific rate limit errors
    if (
        hasattr(error, "__class__")
        and "anthropic" in error.__class__.__module__
    ):
        if any(x in error_str for x in ["rate_limit", "429", "too many"]):
            logger.debug(f"Detected Anthropic rate limit error: {error}")
            return True

    return False


def extract_retry_after(error: Exception) -> float:
    """
    Extract retry-after time from rate limit error if available.

    Args:
        error: The rate limit error

    Returns:
        Retry after time in seconds, or 0 if not found
    """
    # Check for Retry-After header in response
    if hasattr(error, "response") and hasattr(error.response, "headers"):
        retry_after = error.response.headers.get("Retry-After")
        if retry_after:
            try:
                return float(retry_after)
            except ValueError:
                logger.debug(
                    f"Could not parse Retry-After header: {retry_after}"
                )

    # Try to extract from error message
    error_str = str(error)

    # Look for patterns like "try again in X seconds"
    import re

    patterns = [
        r"try again in (\d+(?:\.\d+)?)\s*seconds?",
        r"retry after (\d+(?:\.\d+)?)\s*seconds?",
        r"wait (\d+(?:\.\d+)?)\s*seconds?",
    ]

    for pattern in patterns:
        match = re.search(pattern, error_str, re.IGNORECASE)
        if match:
            try:
                return float(match.group(1))
            except ValueError:
                pass

    return 0
