#  Rubio - Rubika API library for python
#  Copyright (C) 2025-present Rubio <https://github.com/RubioTeam>
#  Github - https://github.com/RubioTeam/rubio.core


from __future__ import annotations

from typing import Optional, Union
from dataclasses import dataclass
from ..config import Object
import html
import rubio.core


@dataclass
class Message(Object):
    """
    **Represents a message in Rubigram.**
        `from rubio.core.types import Message`

    This object can represent different types of messages including text, files,
    stickers, contacts, polls, live locations, and forwarded messages.

    Attributes:
        message_id (`str`):
            Unique identifier of the message.

        text (`Optional[str]`):
            Text content of the message.

        time (`Optional[str]`):
            Timestamp of when the message was sent.

        is_edited (`Optional[bool]`):
            Whether the message has been edited.

        sender_type (`Optional[rubio.core.enums.MessageSenderType]`):
            Type of the sender (User or Bot).

        sender_id (`Optional[str]`):
            Unique identifier of the sender.

        aux_data (`Optional[rubio.core.types.AuxData]`):
            Additional data attached to the message.

        file (`Optional[rubio.core.types.File]`):
            File attached to the message.

        reply_to_message_id (`Optional[str]`):
            ID of the message this is replying to.

        forwarded_from (`Optional[rubio.core.types.ForwardedFrom]`):
            Information about the original sender if forwarded.

        forwarded_no_link (`Optional[str]`):
            Forwarded message without link.

        location (`Optional[rubio.core.types.Location]`):
            Location attached to the message.

        sticker (`Optional[rubio.core.types.Sticker]`):
            Sticker attached to the message.

        contact_message (`Optional[rubio.core.types.ContactMessage]`):
            Contact information attached to the message.

        poll (`Optional[rubio.core.types.Poll]`):
            Poll attached to the message.

        live_location (`Optional[rubio.core.types.LiveLocation]`):
            Live location attached to the message.

        metadata (`Optional[rubio.core.types.MetaData]`):
            Metadata describing text formatting, links, mentions, etc.            

        client (`Optional[rubio.core.Client]`):
            The Rubigram client associated with the message.
    """
    message_id: str
    text: Optional[str] = None
    time: Optional[str] = None
    is_edited: Optional[bool] = None
    sender_type: Optional[Union[str, rubio.core.enums.MessageSenderType]] = None
    sender_id: Optional[str] = None
    aux_data: Optional[rubio.core.types.AuxData] = None
    file: Optional[rubio.core.types.File] = None
    reply_to_message_id: Optional[str] = None
    forwarded_from: Optional[rubio.core.types.ForwardedFrom] = None
    forwarded_no_link: Optional[str] = None
    location: Optional[rubio.core.types.Location] = None
    sticker: Optional[rubio.core.types.Sticker] = None
    contact_message: Optional[rubio.core.types.ContactMessage] = None
    poll: Optional[rubio.core.types.Poll] = None
    live_location: Optional[rubio.core.types.LiveLocation] = None
    metadata: Optional[rubio.core.types.Metadata] = None
    client: Optional[rubio.core.Client] = None

    @property
    def mention(self):
        """
        **Generate an HTML mention for the message sender.**

        Usage:
            message.mention()
            message.mention("Custom Name")

        Returns:
            callable: Function that returns HTML mention string.
        """
        def func(text: Optional[str] = None) -> str:
            if not self.sender_id:
                raise ValueError("Cannot mention without sender_id")

            name = html.escape(text or self.sender_id)
            return f"@@{name}|{self.sender_id}@@"

        return func