"""Error classes for PromptCanvas SDK."""

from typing import Any, Optional


class PromptCanvasError(Exception):
    """Base error class for PromptCanvas SDK."""

    def __init__(self, code: str, message: str, details: Optional[Any] = None):
        super().__init__(message)
        self.code = code
        self.message = message
        self.details = details

    def to_dict(self) -> dict:
        return {
            "code": self.code,
            "message": self.message,
            "details": self.details,
        }


class PromptNotFoundError(PromptCanvasError):
    """Error thrown when prompt is not found."""

    def __init__(self, slug: str, message: Optional[str] = None):
        super().__init__(
            code="PROMPT_NOT_FOUND",
            message=message or f"Prompt '{slug}' not found",
        )
        self.slug = slug


class NoProductionVersionError(PromptCanvasError):
    """Error thrown when prompt has no production version."""

    def __init__(self, slug: str, message: Optional[str] = None):
        super().__init__(
            code="NO_PRODUCTION_VERSION",
            message=message or f"Prompt '{slug}' has no production version. Only production prompts are available via SDK.",
        )
        self.slug = slug


class AuthenticationError(PromptCanvasError):
    """Error thrown when API key is invalid."""

    def __init__(self, message: Optional[str] = None):
        super().__init__(
            code="AUTHENTICATION_ERROR",
            message=message or "Invalid or missing API key",
        )


class RateLimitError(PromptCanvasError):
    """Error thrown when rate limit is exceeded."""

    def __init__(self, retry_after_ms: int = 60000, remaining: int = 0):
        super().__init__(
            code="RATE_LIMIT_EXCEEDED",
            message="Rate limit exceeded. Please slow down.",
        )
        self.retry_after_ms = retry_after_ms
        self.remaining = remaining


class NetworkError(PromptCanvasError):
    """Error thrown when network request fails."""

    def __init__(self, message: str, original_error: Optional[Exception] = None):
        super().__init__(
            code="NETWORK_ERROR",
            message=message,
            details={"original_error": str(original_error)} if original_error else None,
        )
        self.original_error = original_error


class TimeoutError(PromptCanvasError):
    """Error thrown when request times out."""

    def __init__(self, timeout_ms: int):
        super().__init__(
            code="TIMEOUT",
            message=f"Request timed out after {timeout_ms}ms",
        )
        self.timeout_ms = timeout_ms


class MissingVariablesError(PromptCanvasError):
    """Error thrown when required variables are missing."""

    def __init__(self, missing_variables: list):
        super().__init__(
            code="MISSING_VARIABLES",
            message=f"Missing required variables: {', '.join(missing_variables)}",
        )
        self.missing_variables = missing_variables


def map_api_error(error: dict) -> PromptCanvasError:
    """Map API error response to specific error class."""
    code = error.get("code", "UNKNOWN")
    message = error.get("message", "Unknown error")

    if code == "PROMPT_NOT_FOUND":
        return PromptNotFoundError("", message)
    elif code in ("NO_PRODUCTION_VERSION", "NOT_IN_PRODUCTION"):
        return NoProductionVersionError("", message)
    elif code in ("INVALID_API_KEY", "MISSING_API_KEY"):
        return AuthenticationError(message)
    elif code == "RATE_LIMIT_EXCEEDED":
        return RateLimitError()
    else:
        return PromptCanvasError(code, message, error.get("details"))
