from ploneintranet import api as pi_api
from ploneintranet.core import _
from ploneintranet.messaging.interfaces import IMessage
from ploneintranet.notifications.adapters.category_provider import BaseCategory
from ploneintranet.notifications.adapters.category_provider import BaseCategoryProvider
from ploneintranet.notifications.interfaces import IProvideContextUID
from ploneintranet.notifications.interfaces import IResolveContextUID
from zope.component import adapter
from zope.interface import implementer
from zope.interface import provider

import json


@adapter(IMessage)
@implementer(IProvideContextUID)
def message_uid_provider(context):
    """Default adapter that converts the context to a UID
    that will be stored in the notification table.
    """
    uid = json.dumps([context.uid, context.sender, context.recipient])
    return f"ChatMessage:{uid}"


@provider(IResolveContextUID)
def message_uid_resolver(uid):
    """Default utility that converts the UID stored in the notification table
    in to an object.
    """
    uid, sender, recipient = json.loads(uid)
    return pi_api.messaging.get_conversation(sender, recipient)[uid]


class ChatMessagesCategory(BaseCategory):
    name = "chat_messages"
    default_channels = {"desktop", "email"}
    required_channels = set()
    title = _("label_new_chat_messages", default="New chat messages")
    description = ""
    _app_id = "messages"

    @property
    def recipient_ids(self):
        chat = pi_api.messaging.get_inbox(self.context.recipient)[self.context.sender]

        # notify the user if and only if he has not already read all the messages
        if chat.new_messages_count:
            return {self.context.recipient}
        return set()

    def get_message_for(self, notification, with_text=True, highlight=False):
        return _(
            "message_incoming_chat_message",
            default="${actor} sent you a chat message.",
            mapping={
                "actor": notification.logged_event.actor_fullname,
            },
        )


class ChatMessagesCategoryProvider(BaseCategoryProvider):

    category_factories = [ChatMessagesCategory]
