# app/exceptions/auth.py
"""
Authentication and authorization specific exceptions.
"""

from .base import AuthenticationException, AuthorizationException, ConflictException


class InvalidCredentialsException(AuthenticationException):
    """Raised when login credentials are invalid."""

    def __init__(self, message: str = "Invalid username or password"):
        super().__init__(
            message=message,
            error_code="INVALID_CREDENTIALS",
        )


class TokenExpiredException(AuthenticationException):
    """Raised when JWT token has expired."""

    def __init__(self, message: str = "Token has expired"):
        super().__init__(
            message=message,
            error_code="TOKEN_EXPIRED",
        )


class InvalidTokenException(AuthenticationException):
    """Raised when JWT token is invalid or malformed."""

    def __init__(self, message: str = "Invalid token"):
        super().__init__(
            message=message,
            error_code="INVALID_TOKEN",
        )


class InsufficientPermissionsException(AuthorizationException):
    """Raised when user lacks required permissions for an action."""

    def __init__(
        self,
        message: str = "Insufficient permissions for this action",
        required_permission: str | None = None,
    ):
        details = {}
        if required_permission:
            details["required_permission"] = required_permission

        super().__init__(
            message=message,
            error_code="INSUFFICIENT_PERMISSIONS",
            details=details,
        )


class UserNotActiveException(AuthorizationException):
    """Raised when user account is not active."""

    def __init__(self, message: str = "User account is not active"):
        super().__init__(
            message=message,
            error_code="USER_NOT_ACTIVE",
        )


class AdminRequiredException(AuthorizationException):
    """Raised when admin privileges are required."""

    def __init__(self, message: str = "Admin privileges required"):
        super().__init__(
            message=message,
            error_code="ADMIN_REQUIRED",
        )


class UserAlreadyExistsException(ConflictException):
    """Raised when trying to register with existing username/email."""

    def __init__(
        self,
        message: str = "User already exists",
        field: str | None = None,
    ):
        details = {}
        if field:
            details["field"] = field

        super().__init__(
            message=message,
            error_code="USER_ALREADY_EXISTS",
            details=details,
        )
