# This file is part of curious.
#
# curious is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# curious is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with curious.  If not, see <http://www.gnu.org/licenses/>.

"""
Wrappers for Webhook objects.

.. currentmodule:: curious.dataclasses.webhook
"""

import typing

from curious.dataclasses import channel as dt_channel, embed as dt_embed, guild as dt_guild, \
    user as dt_user
from curious.dataclasses.bases import Dataclass
from curious.util import base64ify


class Webhook(Dataclass):
    """
    Represents a webhook on the guild.
    Messages in a guild can be sent by either a Member or a Webhook object - curious makes a key
    distinction between them. These classes are *mostly* compatible and don't require much
    effort to use them generically.
    
    .. code-block:: python3
    
        @event("message_create")
        async def handle_messages(ctx, message: Message):
            author = message.author  # can be Webhook or Member
    """

    __slots__ = "user", "guild_id", "channel_id", "token", "owner", \
                "default_name", "_default_avatar"

    def __init__(self, client, **kwargs) -> None:
        # Use the webhook ID is provided (i.e created from a message object).
        # If that doesn't exist, we use the ID of the data instead (it's probably right!).
        super().__init__(kwargs.get("webhook_id", kwargs.get("id")), cl=client)

        #: The user object associated with this webhook.
        self.user = None  # type: dt_user.User

        #: The ID of the Guild associated with this object.
        self.guild_id = None  # type: int

        #: The ID of the Channel associated with this object.
        self.channel_id = None  # type: int

        #: The token associated with this webhook.
        #: This is None if the webhook was received from a Message object.
        self.token = kwargs.get("token", None)  # type: str

        #: The owner of this webhook.
        self.owner = None  # type: dt_user.User

        #: The default name of this webhook.
        self.default_name = None  # type: str

        #: The default avatar of this webhook.
        self._default_avatar = None  # type: str

    def __repr__(self) -> str:
        return "<Webhook id={} name={} channel={} owner={}>".format(self.id, self.name,
                                                                    repr(self.channel),
                                                                    repr(self.owner))

    __str__ = __repr__

    @property
    def default_avatar_url(self) -> str:
        """
        :return: The default avatar URL for this webhook.
        """
        return "https://cdn.discordapp.com/avatars/{}/{}.png".format(self.id, self._default_avatar)

    @property
    def avatar_url(self) -> str:
        """
        :return: The computed avatar URL for this webhook.
        """
        if self.user.avatar_hash is None:
            return self.default_avatar_url
        return str(self.user.avatar_url)

    @property
    def name(self) -> str:
        """
        :return: The computed name for this webhook.
        """
        # this is kept so you can easily do `message.author.name` all the time.
        return self.user.name or self.default_name

    @property
    def guild(self) -> 'dt_guild.Guild':
        """
        :return: The :class:`.Guild` this webhook is in.
        """