"""
whatsapp.messages
~~~~~~~~~~~~~~~~~~~~~~
Message and Dialog classes for wasup.py.

:copyright: (c) 2025-present June
:license: MIT, see LICENSE for more details.
"""

from typing import TYPE_CHECKING, List, Optional

if TYPE_CHECKING:
    from bindings import ChatContext

__all__ = [
    "TextMessage",
    "ImageMessage",
    "DocumentMessage",
    "VideoMessage",
    "AudioMessage",
    "StickerMessage",
    "ReactionMessage",
    "InteractiveTextMessage",
    "InteractiveListMessage",
    "InteractiveButtonMessage",
    "InteractiveUrlMessage",
    "ActionGroup",
    "ActionGroupItem",
    "ButtonItem",
]


# --- Base Message Classes ---


class TextMessage:
    """Basic text message.

    Attributes:
        channel_id: The channel ID to send the message to.
        to: The recipient user ID (phone number).
        text: The text content of the message.
    """

    def __init__(self, ctx: "ChatContext", message: str):
        """
        Initialize a text message.

        Args:
            ctx: The chat context containing channel and recipient information.
            message: The text content to send.
        """
        self.channel_id = ctx.channel_id
        self.to = ctx.from_id
        self.text = message

    def get_text(self):
        """
        Get the text content of the message.

        Returns:
            The text content.
        """
        return self.text


# --- Media Message Classes ---


class ImageMessage(TextMessage):
    """Image message with optional caption.

    Attributes:
        media_uri: URI/URL to the image file.
        caption: Optional text caption for the image.
    """

    def __init__(self, ctx: "ChatContext", media_uri: str, caption: Optional[str] = None):
        """
        Initialize an image message.

        Args:
            ctx: The chat context.
            media_uri: URL to the image file.
            caption: Optional caption to display with the image.
        """
        super().__init__(ctx, caption or "")
        self.media_uri = media_uri
        self.caption = caption


class DocumentMessage(TextMessage):
    """Document message with file name and optional caption.

    Attributes:
        media_uri: URI/URL to the document file.
        file_name: Name of the document file.
        caption: Optional caption for the document.
    """

    def __init__(self, ctx: "ChatContext", media_uri: str, file_name: str, caption: Optional[str] = None):
        """
        Initialize a document message.

        Args:
            ctx: The chat context.
            media_uri: URL to the document file.
            file_name: The name of the file (for display).
            caption: Optional caption.
        """
        super().__init__(ctx, caption or "")
        self.media_uri = media_uri
        self.file_name = file_name
        self.caption = caption


class VideoMessage(TextMessage):
    """Video message with optional caption.

    Attributes:
        media_uri: URI/URL to the video file.
        caption: Optional caption for the video.
    """

    def __init__(self, ctx: "ChatContext", media_uri: str, caption: Optional[str] = None):
        """
        Initialize a video message.

        Args:
            ctx: The chat context.
            media_uri: URL to the video file.
            caption: Optional caption.
        """
        super().__init__(ctx, caption or "")
        self.media_uri = media_uri
        self.caption = caption


class AudioMessage(TextMessage):
    """Audio message.

    Attributes:
        media_uri: URI/URL to the audio file.
    """

    def __init__(self, ctx: "ChatContext", media_uri: str):
        """
        Initialize an audio message.

        Args:
            ctx: The chat context.
            media_uri: URL to the audio file.
        """
        super().__init__(ctx, "")
        self.media_uri = media_uri


class StickerMessage(TextMessage):
    """Sticker message (animated WebP format).

    Attributes:
        media_uri: URI/URL to the sticker file (should be WebP format).
    """

    def __init__(self, ctx: "ChatContext", media_uri: str):
        """
        Initialize a sticker message.

        Args:
            ctx: The chat context.
            media_uri: URL to the sticker file (animated WebP).
        """
        super().__init__(ctx, "")
        self.media_uri = media_uri


class ReactionMessage(TextMessage):
    """Reaction to a message with emoji.

    Attributes:
        emoji: The emoji character for the reaction.
        message_id: The ID of the message being reacted to.
    """

    def __init__(self, ctx: "ChatContext", emoji: str, message_id: str):
        """
        Initialize a reaction message.

        Args:
            ctx: The chat context.
            emoji: The emoji to react with.
            message_id: The ID of the message to react to.
        """
        super().__init__(ctx, "")
        self.emoji = emoji
        self.message_id = message_id


# --- Interactive Message Classes ---


class InteractiveTextMessage(TextMessage):
    """
    Base class for interactive WhatsApp messages.

    Provides common structure for interactive messages: body, header, footer.
    Subclasses implement specific interactive types (buttons, lists, URLs).

    Attributes:
        body: The main message content.
        header: Optional header text displayed above the body.
        footer: Optional footer text displayed below the message.
    """

    def __init__(self, ctx: "ChatContext", body: str, header: Optional[str] = None, footer: Optional[str] = None):
        """
        Initialize an interactive text message.

        Args:
            ctx: The chat context.
            body: The main message text.
            header: Optional header text.
            footer: Optional footer text.
        """
        super().__init__(ctx, body)
        self.body = body
        self.header = header
        self.footer = footer


# --- Interactive Message Supporting Classes ---


class ActionGroupItem:
    """Individual item in an action group (list option).

    Attributes:
        id: Unique identifier for the action.
        title: Display title of the action.
        description: Optional description of the action.
    """

    def __init__(self, id: str, title: str, description: Optional[str] = None):
        """
        Initialize an action group item.

        Args:
            id: Unique ID for this action.
            title: The text to display for this option.
            description: Optional additional description.
        """
        self.id = id
        self.title = title
        self.description = description


class ActionGroup:
    """Group of action items for list messages.

    Attributes:
        title: The title/section header for this group of actions.
        items: List of ActionGroupItem objects in this group.
    """

    def __init__(self, title: str, items: List[ActionGroupItem]):
        """
        Initialize an action group.

        Args:
            title: The section header for this group of options.
            items: List of ActionGroupItem to include in this group.
        """
        self.title = title
        self.items = items


class ButtonItem:
    """Button for quick reply or call-to-action.

    Attributes:
        id: Unique identifier for the button.
        title: Text displayed on the button.
    """

    def __init__(self, id: str, title: str):
        """
        Initialize a button item.

        Args:
            id: Unique ID returned when button is pressed.
            title: Text to display on the button.
        """
        self.id = id
        self.title = title


# --- Interactive Message Subclasses ---


class InteractiveListMessage(InteractiveTextMessage):
    """
    Interactive list message with grouped options.

    Users can select from a menu of options organized in groups.
    WhatsApp displays this as a scrollable list.

    Attributes:
        groups: List of ActionGroup objects containing the menu options.
        button_title: The text on the button that opens the list menu.
    """

    def __init__(
        self,
        ctx: "ChatContext",
        body: str,
        groups: List[ActionGroup],
        button_title: str = "Select",
        header: Optional[str] = None,
        footer: Optional[str] = None,
    ):
        """
        Initialize an interactive list message.

        Args:
            ctx: The chat context.
            body: The main message text.
            groups: List of ActionGroup objects with options.
            button_title: Text for the button that opens the list. Defaults to "Select".
            header: Optional header text above the message body.
            footer: Optional footer text below the message body.
        """
        super().__init__(ctx, body, header, footer)
        self.groups = groups
        self.button_title = button_title


class InteractiveButtonMessage(InteractiveTextMessage):
    """
    Interactive button message with quick reply buttons.

    Maximum of 3 buttons allowed by WhatsApp platform.

    Attributes:
        buttons: List of ButtonItem objects (max 3).
    """

    def __init__(
        self,
        ctx: "ChatContext",
        body: str,
        buttons: List[ButtonItem],
        header: Optional[str] = None,
        footer: Optional[str] = None,
    ):
        """
        Initialize an interactive button message.

        Args:
            ctx: The chat context.
            body: The main message text.
            buttons: List of ButtonItem objects. Max 3 buttons allowed.
            header: Optional header text.
            footer: Optional footer text.

        Raises:
            ValueError: If more than 3 buttons are provided.
        """
        super().__init__(ctx, body, header, footer)
        if len(buttons) > 3:
            raise ValueError("WhatsApp allows maximum 3 buttons")
        self.buttons = buttons


class InteractiveUrlMessage(InteractiveTextMessage):
    """
    Interactive message with a call-to-action URL button.

    Opens a URL when the user taps the button.

    Attributes:
        url: The URL to open when button is tapped.
        title: Text to display on the call-to-action button.
    """

    def __init__(
        self,
        ctx: "ChatContext",
        body: str,
        url: str,
        title: str,
        header: Optional[str] = None,
        footer: Optional[str] = None,
    ):
        """
        Initialize an interactive URL message.

        Args:
            ctx: The chat context.
            body: The main message text.
            url: The URL to open when the button is pressed.
            title: Text to display on the button.
            header: Optional header text.
            footer: Optional footer text.
        """
        super().__init__(ctx, body, header, footer)
        self.url = url
        self.title = title
