# app/modules/messaging/exceptions.py
"""
Messaging module exceptions.

This module provides exception classes for messaging operations including:
- Conversation management
- Message handling
- Attachment processing
"""

from app.exceptions.base import BusinessLogicException, ResourceNotFoundException

__all__ = [
    "ConversationNotFoundException",
    "MessageNotFoundException",
    "ConversationClosedException",
    "MessageAttachmentException",
    "UnauthorizedConversationAccessException",
    "InvalidConversationTypeException",
    "InvalidRecipientTypeException",
    "AttachmentNotFoundException",
]


class ConversationNotFoundException(ResourceNotFoundException):
    """Raised when a conversation is not found."""

    def __init__(self, conversation_identifier: str):
        super().__init__(
            resource_type="Conversation",
            identifier=conversation_identifier,
            message=f"Conversation '{conversation_identifier}' not found",
            error_code="CONVERSATION_NOT_FOUND",
        )


class MessageNotFoundException(ResourceNotFoundException):  # noqa: MOD025
    """Raised when a message is not found."""

    def __init__(self, message_identifier: str):
        super().__init__(
            resource_type="Message",
            identifier=message_identifier,
            message=f"Message '{message_identifier}' not found",
            error_code="MESSAGE_NOT_FOUND",
        )


class ConversationClosedException(BusinessLogicException):
    """Raised when trying to send message to a closed conversation."""

    def __init__(self, conversation_id: int):
        super().__init__(
            message=f"Cannot send message to closed conversation {conversation_id}",
            error_code="CONVERSATION_CLOSED",
            details={"conversation_id": conversation_id},
        )


class MessageAttachmentException(BusinessLogicException):
    """Raised when attachment validation fails."""

    def __init__(self, message: str, details: dict | None = None):
        super().__init__(
            message=message,
            error_code="MESSAGE_ATTACHMENT_INVALID",
            details=details,
        )


class UnauthorizedConversationAccessException(BusinessLogicException):  # noqa: MOD025
    """Raised when user tries to access a conversation they don't have access to."""

    def __init__(self, conversation_id: int):
        super().__init__(
            message=f"You do not have access to conversation {conversation_id}",
            error_code="CONVERSATION_ACCESS_DENIED",
            details={"conversation_id": conversation_id},
        )


class InvalidConversationTypeException(BusinessLogicException):
    """Raised when conversation type is not valid for the operation."""

    def __init__(self, message: str, allowed_types: list[str] | None = None):
        super().__init__(
            message=message,
            error_code="INVALID_CONVERSATION_TYPE",
            details={"allowed_types": allowed_types} if allowed_types else None,
        )


class InvalidRecipientTypeException(BusinessLogicException):
    """Raised when recipient type doesn't match conversation type."""

    def __init__(self, conversation_type: str, expected_recipient_type: str):
        super().__init__(
            message=f"{conversation_type} conversations require a {expected_recipient_type} recipient",
            error_code="INVALID_RECIPIENT_TYPE",
            details={
                "conversation_type": conversation_type,
                "expected_recipient_type": expected_recipient_type,
            },
        )


class AttachmentNotFoundException(ResourceNotFoundException):
    """Raised when an attachment is not found."""

    def __init__(self, attachment_id: int | str):
        super().__init__(
            resource_type="Attachment",
            identifier=str(attachment_id),
            message=f"Attachment '{attachment_id}' not found",
            error_code="ATTACHMENT_NOT_FOUND",
        )
