from BTrees.OOBTree import OOTreeSet
from plone import api
from plone.memoize.view import memoize
from ploneintranet.layout.browser.base import BaseView
from ploneintranet.layout.interfaces import IDiazoNoTemplate
from ploneintranet.news.interfaces import IBannerWithHero
from ploneintranet.news.interfaces import IBannerWithIcon
from zope.annotation.interfaces import IAnnotations
from zope.interface import implementer


@implementer(IDiazoNoTemplate)
class View(BaseView):
    """Display the tip of the day (if any available)"""

    tip_ifaces = [IBannerWithIcon, IBannerWithHero]
    tod_key = "ploneintranet.news.read_tods"

    @property
    @memoize
    def has_hero(self):
        """Check if we should display the hero image"""
        return IBannerWithHero.providedBy(self.tip)

    @property
    @memoize
    def css_class(self):
        """Check if we should display the hero image"""
        if self.has_hero:
            return "has-hero"
        return f"icon-{self.tip.banner_icon}"

    def search_tips(self):
        """Search all the tips"""
        return api.content.find(
            object_provides=self.tip_ifaces, sort_on="modified", sort_order="reverse"
        )

    @property
    @memoize
    def tip(self):
        """Return the tip of the day for this user"""
        brains = self.search_tips()
        read_uids = IAnnotations(self.user, {}).get(self.tod_key, [])
        unpublished_states = api.portal.get_registry_record(
            "ploneintranet.news.unpublished_states", default=["private", "pending"]
        )
        for brain in brains:
            if (
                brain.review_state not in unpublished_states
                and brain.UID not in read_uids
            ):
                return brain.getObject()

    def mark_read(self, uids):
        """Mark the given news as read"""
        if not uids:
            return
        if isinstance(uids, str):
            uids = [uids]
        annotations = IAnnotations(self.user, None)
        if annotations is None:
            return  # nothing to do: not a proper user
        if self.tod_key not in annotations:
            annotations[self.tod_key] = OOTreeSet()
        keys = annotations[self.tod_key]
        keys.update(uids)

    def close(self):
        """Mark all the tips as read: the tip will not appear for a while"""
        brains = self.search_tips()
        self.mark_read(brain.UID for brain in brains)

    def read(self):
        """I mark the given news as read and redirect to its view."""
        uid = self.request.get("read")
        if not uid:
            raise ValueError("Invalid value for uid: %r" % uid)
        obj = api.content.get(UID=uid)
        self.request.response.redirect(obj.absolute_url())

    def __call__(self):
        if self.is_posting():
            self.close()
        elif self.request.get("read"):
            return self.read()
        return super().__call__()
