"""
Custom exceptions for Reno API errors.
"""

from typing import Optional


class RenoError(Exception):
    """Base exception for Reno API errors."""
    
    def __init__(self, code: int, message: str, details: Optional[str] = None):
        self.code = code
        self.message = message
        self.details = details
        super().__init__(f"[{code}] {message}")

    def user_friendly(self) -> str:
        """Return a user-friendly error message based on the code."""
        friendly = {
            1001: ("Invalid API Key Format", "Check that your key starts with 'reno_sk_'."),
            1002: ("Invalid API Key", "Verify your API key in the dashboard."),
            1003: ("Missing API Key", "Add an 'Authorization: Bearer <key>' header."),
            1004: ("Expired API Key", "Generate a new API key."),
            1005: ("Revoked API Key", "Create a new key; this one was revoked."),
            1006: ("Insufficient Permissions", "Check your subscription tier."),
            1007: ("IP Not Whitelisted", "Add your IP to the whitelist."),
            1008: ("Account Suspended", "Contact support."),
            2001: ("Malformed Request", "Ensure your JSON is valid."),
            2002: ("Missing Model", "Include a 'model' field."),
            2003: ("Missing Messages", "Include a 'messages' array."),
            2004: ("Empty Message", "Message content cannot be empty."),
            2005: ("Invalid Role", "Role must be 'user', 'assistant', or 'system'."),
            2006: ("Too Many Messages", "Reduce message history."),
            2007: ("Invalid Temperature", "Temperature must be between 0 and 2."),
            2008: ("Invalid max_tokens", "max_tokens must be a positive integer."),
            2009: ("Subscription Error", "Check your subscription status."),
            3001: ("Model Not Found", "Try a different model."),
            3002: ("Model Not Loaded", "Wait a moment and retry."),
            3003: ("Model Loading", "Please wait, model is loading."),
            3004: ("Model at Capacity", "Try again later or switch models."),
            3005: ("Unsupported Parameter", "This model doesn't support that parameter."),
            3006: ("Model Deprecated", "Upgrade to a newer model."),
            3007: ("Model Unavailable", "Try again later."),
            4001: ("Context Length Exceeded", "Shorten your conversation."),
            4002: ("Max Tokens Limit", "Reduce max_tokens or prompt length."),
            4003: ("Response Truncated", "Increase max_tokens if needed."),
            4004: ("Prompt Too Long", "Shorten your prompt."),
            4005: ("Token Estimation Failed", "Try a simpler request."),
            5001: ("Rate Limit Exceeded", "Slow down your request rate."),
            5002: ("Daily Quota Exceeded", "Upgrade or wait until tomorrow."),
            5003: ("Monthly Quota Exceeded", "Upgrade or wait until next month."),
            5004: ("Concurrent Limit", "Wait for other requests to finish."),
            5005: ("Rate Limit Unknown", "Try again later."),
            5006: ("Daily Token Limit", "Upgrade or wait for reset."),
            6001: ("Server Overloaded", "Please wait and retry."),
            6002: ("Service Unavailable", "Check status page."),
            6003: ("Timeout", "Try a shorter prompt."),
            6004: ("Database Error", "Retry; if persists contact support."),
            6005: ("Upstream Error", "Try again later."),
            6006: ("Maintenance Mode", "Scheduled maintenance - check status."),
            7001: ("Content Policy Violation", "Review content guidelines."),
            7002: ("NSFW Detected", "NSFW content not allowed."),
            7003: ("Prompt Blocked", "Moderation blocked your prompt."),
            7004: ("Response Filtered", "Try rephrasing."),
            8001: ("Insufficient Credits", "Purchase more credits."),
            8002: ("Payment Required", "Update billing information."),
            8003: ("Trial Expired", "Upgrade to a paid plan."),
            8004: ("Billing Error", "Check payment details."),
            9001: ("Internal Error", "Try again; contact support if persists."),
            9002: ("Not Implemented", "Feature not available yet."),
            9003: ("Feature Disabled", "Check documentation."),
            9004: ("Unexpected Error", "Contact support."),
        }
        title, suggestion = friendly.get(
            self.code, 
            ("Unknown Error", "No suggestion available.")
        )
        return f"{title}: {self.message}\n💡 {suggestion}"


class RenoConnectionError(RenoError):
    """Raised when connection to Reno API fails."""
    
    def __init__(self, message: str = "Failed to connect to Reno API"):
        super().__init__(code=6002, message=message)


class RenoTimeoutError(RenoError):
    """Raised when request to Reno API times out."""
    
    def __init__(self, message: str = "Request timed out"):
        super().__init__(code=6003, message=message)
