"""Copyright © 2025 sunset-hue

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""

import typing
from datetime import datetime


if typing.TYPE_CHECKING:
    from ..resourceid import ResourceID
    from .user import User
    from .attach import Attachment


class ChannelMention:
    def __init__(self, _data: dict):
        self.id: ResourceID = ResourceID(_data["id"])
        self.guild_id: ResourceID = ResourceID(_data["guild_id"])
        self.name: str = _data["name"]


class Message:
    def __init__(self, _data: dict):
        self._dict = _data

    @property
    def id(self) -> ResourceID:
        """The ID of this message."""
        return ResourceID(self._dict["id"])

    @property
    def channel_id(self) -> ResourceID:
        """The ID of the channel that this message is in."""
        return ResourceID(self._dict["channel_id"])

    @property
    def author(self) -> User:
        """The author of this message. May not be a valid user, if this message was generated by a webhook."""
        return User(self._dict["author"])

    @property
    def content(self) -> str:
        """The contents in this message. (Not an empty string if the Message Contents privileged intent is enabled)"""
        return self._dict["content"]

    @property
    def sent_at(self) -> datetime:
        """The `datetime.datetime` object representing when this message was sent."""
        return datetime.fromisoformat(self._dict["timestamp"])

    @property
    def edited_timestamp(self) -> datetime | None:
        """The `datetime.datetime` object representing when this message was edited, if applicable."""
        return (
            datetime.fromisoformat(self._dict["edited_timestamp"])
            if self._dict.get("edited_timestamp")
            else None
        )

    @property
    def tts(self) -> bool:
        """Whether this message has TTS enabled on it, meaning TTS reads this message out loud."""
        return self._dict["tts"]

    @property
    def mentions_everyone(self) -> bool:
        """Whether this message mentions everyone in a group DM or channel."""
        return self._dict["mentions_everyone"]

    @property
    def mentions(self) -> list[User] | list:
        """The `inkcord.User` objects representing the mentions in this message."""
        return [
            User(user)
            for user in self._dict["mentions"]
            if len(self._dict["mentions"]) > 1
        ]
        # the > 1 is probably useless but i would rather keep this check

    @property
    def mention_roles(self) -> list[ResourceID]:
        """The list of role ID's that represent the roles that were mentioned in this message."""
        return [ResourceID(id) for id in self._dict["mention_roles"]]

    @property
    def channel_mentions(self) -> list[ChannelMention] | None:
        """The list of channels that were mentioned. The data is returned through a inkcord.ChannelMention object, which contains minimal info about the mentioned channel."""
        return (
            [ChannelMention(x) for x in self._dict["channel_mentions"]]
            if self._dict.get("channel_mentions")
            else None
        )

    @property
    def attachments(self) -> list[Attachment] | None:
        """The list of attachments that were in this message, if applicable."""
        return (
            [Attachment(x) for x in self._dict["attachments"]]
            if self._dict.get("attachments")
            else None
        )
