from logging import getLogger
from plone import api
from plone.app.contenttypes.browser import link_redirect_view
from plone.memoize import view
from ploneintranet import api as pi_api
from ploneintranet.layout.interfaces import IDiazoDashboardTemplate
from ploneintranet.library.behaviors.publish import IPublishWidely
from ploneintranet.library.browser import utils
from ploneintranet.library.browser.views import LibraryBaseView
from ploneintranet.network.behaviors.metadata import ICategorization
from zope.interface import implementer

import six.moves.urllib.error
import six.moves.urllib.parse
import six.moves.urllib.request

log = getLogger(__name__)


@implementer(IDiazoDashboardTemplate)
class ContentView(LibraryBaseView):

    show_sections_navigation = True

    @view.memoize
    def parent(self):
        return self.context.aq_parent

    @view.memoize
    def siblings(self):
        return utils.children_of(self.context.aq_parent)

    @view.memoize
    def subjects(self):
        base_url = self.app().absolute_url()
        _tags = ICategorization(self.context).subjects
        return [
            dict(
                title=_tag,
                absolute_url="%s/tag/%s"
                % (base_url, six.moves.urllib.parse.quote(_tag)),
            )
            for _tag in _tags
        ]

    @property
    def source_url(self):
        adapted = IPublishWidely(self.context)
        source = adapted.source()
        if source:
            return f"{source.absolute_url()}/view?show_sidebar=1"

    def can_edit(self):
        adapted = IPublishWidely(self.context)
        context = adapted.source() or self.context
        return api.user.has_permission("Modify portal content", obj=context)

    def timestamp(self):
        pdf = pi_api.previews.get_pdf(self.context)
        if pdf:
            return pdf._p_mtime
        return self.context._p_mtime

    def maybe_update_wf(self):
        """Check if we should update the workflow state.

        # TODO: this should be componentized, the workflow menu should post to
        # itself but that requires proto to embrace that philosophy
        """
        if self.request.method != "POST":
            return
        transition = self.request.get("workflow_action")
        if not transition:
            return
        # It may be that the transition is actually the current state
        if transition == api.content.get_state(self.context):
            return
        api.content.transition(obj=self.context, transition=transition)
        self.context.reindexObject()

    def __call__(self):
        self.maybe_update_wf()
        return super().__call__()


class LinkRedirectView(ContentView, link_redirect_view.LinkRedirectView):
    """Always redirect internal links, even if the user has edit permissions.
    (Editing is done in Barceloneta)
    External links should instead have a template showing the link.
    """

    def _is_external(self):
        """Check if this is an external link"""
        if not self.context.remoteUrl:
            return False
        portal_url = api.portal.get().absolute_url()
        return not self.context.remoteUrl.startswith(portal_url)

    def _is_video_link(self):
        """Check if this link refers to a video.
        It is used to show a video player instead of the regular preview
        """
        return self.context.content_type() == "text/x-uri-video"

    def _is_youtube_link(self):
        return self.context.content_type() == "text/x-uri-youtube"

    def __call__(self):
        self.maybe_update_wf()
        self.request.unwrapped = True
        if self._is_external():
            return self.index()
        return self.request.RESPONSE.redirect(self.absolute_target_url())
