"""
Custom API Exception Classes
"""
from datetime import datetime
from typing import Any, Dict, List, Union


class APIException(Exception):
    """
    Custom API exception for structured error handling.
    
    Provides a consistent way to raise and handle application-specific errors
    with detailed context information.
    """
    
    def __init__(
        self,
        message: str = "Something went wrong!",
        status_code: int = 400,
        error: Union[Dict[str, Any], List[Dict[str, Any]], str] = None,
        module: str = None,
        request_id: str = None,
    ):
        """
        Initialize APIException.
        
        Args:
            message: Human-readable error message
            status_code: HTTP status code
            error: Detailed error information
            module: Module/component where error occurred
            request_id: Unique request identifier
        """
        self.message = message
        self.status_code = status_code
        self.error = error or message
        self.module = module
        self.request_id = request_id
        self.timestamp = datetime.utcnow().isoformat() + "Z"
        
        super().__init__(self.message)
    
    def __str__(self) -> str:
        """String representation of the exception"""
        return f"{self.message} (Status: {self.status_code})"
    
    def __repr__(self) -> str:
        """Detailed representation of the exception"""
        return (
            f"APIException(message='{self.message}', "
            f"status_code={self.status_code}, "
            f"module='{self.module}', "
            f"request_id='{self.request_id}')"
        )


class ValidationException(APIException):
    """Exception for validation errors"""
    
    def __init__(
        self,
        message: str = "Validation failed",
        error: Union[Dict[str, Any], List[Dict[str, Any]], str] = None,
        **kwargs
    ):
        super().__init__(
            message=message,
            status_code=422,
            error=error,
            **kwargs
        )


class NotFoundError(APIException):
    """Exception for resource not found errors"""
    
    def __init__(
        self,
        message: str = "Resource not found",
        **kwargs
    ):
        super().__init__(
            message=message,
            status_code=404,
            **kwargs
        )


class UnauthorizedError(APIException):
    """Exception for authentication/authorization errors"""
    
    def __init__(
        self,
        message: str = "Unauthorized access",
        **kwargs
    ):
        super().__init__(
            message=message,
            status_code=401,
            **kwargs
        )


class ForbiddenError(APIException):
    """Exception for forbidden access errors"""
    
    def __init__(
        self,
        message: str = "Access forbidden",
        **kwargs
    ):
        super().__init__(
            message=message,
            status_code=403,
            **kwargs
        )


class ConflictError(APIException):
    """Exception for resource conflict errors"""
    
    def __init__(
        self,
        message: str = "Resource conflict",
        **kwargs
    ):
        super().__init__(
            message=message,
            status_code=409,
            **kwargs
        )


class InternalServerError(APIException):
    """Exception for internal server errors"""
    
    def __init__(
        self,
        message: str = "Internal server error",
        **kwargs
    ):
        super().__init__(
            message=message,
            status_code=500,
            **kwargs
        )
