from typing import Any, Optional


class AppError(Exception):
    def __init__(
        self,
        message: str,
        code: str = "APP_ERROR",
        status_code: int = 400,
        details: Optional[list[dict[str, Any]]] = None,
    ):
        self.message = message
        self.code = code
        self.status_code = status_code
        self.details = details or []
        super().__init__(message)


class NotFoundError(AppError):
    def __init__(self, message: str = "Resource not found"):
        super().__init__(message=message, code="NOT_FOUND", status_code=404)


class UnauthorizedError(AppError):
    def __init__(self, message: str = "Unauthorized"):
        super().__init__(message=message, code="UNAUTHORIZED", status_code=401)


class ForbiddenError(AppError):
    def __init__(self, message: str = "Forbidden"):
        super().__init__(message=message, code="FORBIDDEN", status_code=403)


class ValidationError(AppError):
    def __init__(self, message: str, details: Optional[list[dict[str, Any]]] = None):
        super().__init__(message=message, code="VALIDATION_ERROR", status_code=422, details=details)


class RateLimitError(AppError):
    def __init__(self, message: str = "Too many requests"):
        super().__init__(message=message, code="RATE_LIMIT_EXCEEDED", status_code=429)
