from Acquisition import aq_inner
from logging import getLogger
from plone import api
from plone.memoize import ram
from plone.memoize.view import memoize
from plone.protect.interfaces import IDisableCSRFProtection
from ploneintranet import api as pi_api
from ploneintranet.core import _
from ploneintranet.docconv.client.aspectratios import AspectRatios
from ploneintranet.docconv.client.interfaces import IPreviewSettings
from ploneintranet.layout.browser.proto import _5min_cache_key
from ploneintranet.layout.utils import youtube_url
from ploneintranet.workspace.behaviors.file import IFileField
from Products.Five import BrowserView
from zope.interface import alsoProvides

logger = getLogger(__name__)


class PreviewsView(BrowserView):
    """A simple view that shows only the previews of the context"""

    @property
    @memoize
    def successfully_converted(self):
        # if New Style (SVG) previews, check api
        return pi_api.previews.successfully_converted(self.context)

    @memoize
    def previews(self, page=None):
        previews = pi_api.previews.get_preview_urls(
            self.context, with_timestamp=True, small=False
        )
        if page:
            return previews[int(page) - 1]
        return previews[: self.num_preview_limit]

    @memoize
    def aspect_ratio(self, page):
        if not pi_api.previews.has_pdf(self.context):
            return "auto"
        page = int(page)
        if (
            not self.preview_storage.aspect_ratios
            # num_preview_limit may have changed since initial extraction
            or len(self.preview_storage.aspect_ratios) < page
        ):
            alsoProvides(self.request, IDisableCSRFProtection)
            AspectRatios(self.context)(self.num_preview_limit)
        return self.preview_storage.aspect_ratios[page - 1]

    @memoize
    def aspect_ratio_style(self, page):
        """Hardstyle aspect-ratio only if there is one"""
        return (
            self.aspect_ratio(page) and f"aspect-ratio: {self.aspect_ratio(page)}" or ""
        )

    @property
    @memoize
    def show_previews(self):
        """Check if we want to show previews"""
        no_previews_types = ("Document",)
        return (
            not self.is_videotype
            and not self.is_audiotype
            and self.context.portal_type not in no_previews_types
        )

    @property
    @memoize
    def is_audiotype(self):
        return IFileField(self.context, False) and IFileField(self.context).is_audiotype

    @property
    @memoize
    def is_videotype(self):
        return IFileField(self.context, False) and IFileField(self.context).is_videotype

    @property
    def num_preview_pages(self):
        return pi_api.previews.num_pages(self.context)

    @property
    @ram.cache(_5min_cache_key)
    def num_preview_limit(self):
        return api.portal.get_registry_record(
            "ploneintranet.docconv.num_previews", default=100
        )

    @property
    @memoize
    def converting(self):
        if not self.is_allowed_document_type():
            return False
        return pi_api.previews.converting(self.context)

    @property
    @memoize
    def preview_storage(self):
        return IPreviewSettings(self.context)

    @memoize
    def is_allowed_document_type(self):
        return pi_api.previews.is_allowed_document_type(self.context)

    @property
    @memoize
    def preview_info(self):
        """Return a message to the user who is looking for previews"""
        if not self.is_allowed_document_type():
            return _("Page views are not supported for this file format.")
        if self.converting:
            return _("Page views being generated.")

        storage = self.preview_storage
        exception_msg = storage.exception_msg
        if not exception_msg:
            return _("It was not possible to generate page views for this document.")
        if "Command Line Error: Incorrect password" in exception_msg:
            return _(
                "Cannot generate preview because the file "
                "appears to be password protected."
            )
        logger.warning(
            "Unknown exception occured while generating preview: %r", exception_msg
        )
        return _("It was not possible to generate page views for this document.")

    def image_url(self, obj=None):
        """The img-url used to construct the img-tag."""
        context = aq_inner(obj or self.context)
        if getattr(context, "image", None) is not None:
            return f"{context.absolute_url()}/@@images/image"


class LinkPreviewsView(PreviewsView):

    _youtube_url_template = "https://www.youtube-nocookie.com/embed/{v}"

    @property
    def youtube_url(self):
        """Try to sniff the youtube URL video id and to create a proper url for it"""
        return youtube_url(self.context.remoteUrl, self._youtube_url_template)
