from plone import api
from plone.app.contenttypes.content import Image
from plone.i18n.normalizer.interfaces import IURLNormalizer
from plone.memoize.view import memoize
from ploneintranet import api as pi_api
from ploneintranet.attachments import utils
from ploneintranet.attachments.attachments import IAttachmentStorage
from ploneintranet.docconv.client.handlers import handle_file_creation
from ploneintranet.docconv.client.interfaces import IPreviewSettings
from Products.Five.browser import BrowserView
from zope.component import getUtility
from zope.container.interfaces import DuplicateIDError

import logging

log = logging.getLogger(__name__)


class UploadAttachments(BrowserView):
    @property
    @memoize
    def fallback_thumbs_urls(self):
        """Return a dummy image thumbnails

        BBB: Ask for a better image :)
        See #122
        """
        return [pi_api.previews.fallback_image_url(api.portal.get())]

    def get_file_thumbs_urls(self, attachment):
        """
        thumbs provided by docconv. Only returning the front page.
        """
        if pi_api.previews.has_previews(attachment) is not True:
            return None
        return [attachment.absolute_url() + "/svg"]

    def get_num_pages(self, attachment):
        return pi_api.previews.num_pages(attachment)

    def get_description(self, attachment):
        settings = IPreviewSettings(attachment)
        blob_files = settings.blob_files or {}
        good_keys = sorted(key for key in blob_files if key.startswith("text"))
        description = ""
        if len(good_keys) > 0:
            with blob_files[good_keys[0]].open() as th:
                description = th.read()
        return description

    def get_image_thumbs_urls(self, image):
        """
        If we have an Image or a File object,
        we ask the Plone scale machinery for a URL
        """
        images = api.content.get_view("images", image, self.request)
        try:
            urls = [images.scale(scale="preview").absolute_url()]
        except BaseException:
            log.error("Preview url generation failed")
            urls = []
        return urls

    def get_thumbs_urls(self, attachment):
        """This will return the URL for the thumbs of the attachment"""
        # We first ask pi_api for a URL
        # This returns previews for images and files
        urls = self.get_file_thumbs_urls(attachment)
        if urls:
            return urls

        # If we have an image we return the usual preview url
        if isinstance(attachment, (Image,)):
            urls = self.get_image_thumbs_urls(attachment)
        if urls:
            return urls

        # If every other method fails return a fallback
        return self.fallback_thumbs_urls

    def __call__(self):
        token = self.request.get("attachment-form-token")
        uploaded_attachments = self.request.get("form.widgets.attachments")
        if not uploaded_attachments:
            return self.index()

        normalizer = getUtility(IURLNormalizer)
        self.attachments = []
        attachments = IAttachmentStorage(self.context)

        attachment_objs = utils.extract_attachments(uploaded_attachments)
        for obj in attachment_objs:
            obj.id = normalizer.normalize(f"{token}-{obj.id}")
            try:
                attachments.add(obj)
            except DuplicateIDError:
                pass
            obj = attachments.get(obj.id)
            try:
                handle_file_creation(obj, None, asynchronous=False)
            except Exception as e:
                log.warning(
                    "Could not get previews for attachment: {}, "
                    "{}: {}".format(obj.id, e.__class__.__name__, e)
                )
            self.attachments.append(obj)

        return self.index()


class UploadStatusAttachments(UploadAttachments):
    """Separate class since it handles permissions differently"""
