from Acquisition import aq_base
from Acquisition import aq_inner
from plone.app.contenttypes import _
from plone.app.contenttypes.behaviors.leadimage import ILeadImage
from plone.app.contenttypes.interfaces import IFolder
from plone.app.contenttypes.interfaces import IImage
from plone.app.vocabularies.metadatafields import get_field_label
from plone.base.batch import Batch
from plone.base.interfaces import ISecuritySchema
from plone.base.interfaces import ISiteSchema
from plone.base.utils import safe_callable
from plone.event.interfaces import IEvent
from plone.memoize.view import memoize
from plone.registry.interfaces import IRegistry
from Products.Five import BrowserView
from zope.component import getMultiAdapter
from zope.component import getUtility
from zope.contentprovider.interfaces import IContentProvider

import random


class FolderView(BrowserView):
    text_class = None
    _plone_view = None
    _portal_state = None
    _pas_member = None

    @property
    def plone_view(self):
        if not self._plone_view:
            self._plone_view = getMultiAdapter(
                (self.context, self.request), name="plone"
            )
        return self._plone_view

    @property
    def portal_state(self):
        if not self._portal_state:
            self._portal_state = getMultiAdapter(
                (self.context, self.request), name="plone_portal_state"
            )
        return self._portal_state

    @property
    def pas_member(self):
        if not self._pas_member:
            self._pas_member = getMultiAdapter(
                (self.context, self.request), name="pas_member"
            )
        return self._pas_member

    @property
    def b_size(self):
        b_size = (
            getattr(self.request, "b_size", None)
            or getattr(self.request, "limit_display", None)
            or 20
        )
        return int(b_size)

    @property
    def b_start(self):
        b_start = getattr(self.request, "b_start", None) or 0
        return int(b_start)

    def results(self, **kwargs):
        """Return a content listing based result set with contents of the
        folder.

        :param **kwargs: Any keyword argument, which can be used for catalog
                         queries.
        :type  **kwargs: keyword argument

        :returns: plone.app.contentlisting based result set.
        :rtype: ``plone.app.contentlisting.interfaces.IContentListing`` based
                sequence.
        """
        # Extra filter
        kwargs.update(self.request.get("contentFilter", {}))
        if "object_provides" not in kwargs:  # object_provides is more specific
            kwargs.setdefault("portal_type", self.friendly_types)
        kwargs.setdefault("batch", True)
        kwargs.setdefault("b_size", self.b_size)
        kwargs.setdefault("b_start", self.b_start)
        kwargs.setdefault("orphan", 1)

        listing = aq_inner(self.context).restrictedTraverse("@@folderListing", None)
        if listing is None:
            return []
        results = listing(**kwargs)
        return results

    def batch(self):
        batch = Batch(self.results(), size=self.b_size, start=self.b_start, orphan=1)
        return batch

    def normalizeString(self, text):
        return self.plone_view.normalizeString(text)

    def toLocalizedTime(self, time, long_format=None, time_only=None):
        return self.plone_view.toLocalizedTime(time, long_format, time_only)

    @property
    def friendly_types(self):
        return self.portal_state.friendly_types()

    @property
    def isAnon(self):
        return self.portal_state.anonymous()

    @property
    def navigation_root_url(self):
        return self.portal_state.navigation_root_url()

    @property
    def use_view_action(self):
        registry = getUtility(IRegistry)
        return registry.get("plone.types_use_view_action_in_listings", [])

    @property
    def show_about(self):
        registry = getUtility(IRegistry)
        settings = registry.forInterface(ISecuritySchema, prefix="plone")
        show_about = getattr(settings, "allow_anon_views_about", False)
        return show_about or not self.isAnon

    @property
    def text(self):
        textfield = getattr(aq_base(self.context), "text", None)
        text = (
            textfield.output_relative_to(self.context)
            if getattr(textfield, "output_relative_to", None)
            else None
        )
        if text:
            self.text_class = (
                "stx"
                if textfield.mimeType
                in ("text/structured", "text/x-rst", "text/restructured")
                else "plain"
            )
        return text

    @property
    def tabular_fields(self):
        ret = []
        ret.append("Title")
        if self.show_about:
            ret.append("Creator")
        ret.append("Type")
        if self.show_about:
            ret.append("ModificationDate")
        return ret

    def tabular_field_label(self, field):
        """Return the internationalized label (Message object) corresponding
        to the field.
        """
        return get_field_label(field)

    def tabular_fielddata(self, item, fieldname):
        value = getattr(item, fieldname, "")
        if safe_callable(value):
            value = value()
        if fieldname in [
            "CreationDate",
            "ModificationDate",
            "Date",
            "EffectiveDate",
            "ExpirationDate",
            "effective",
            "expires",
            "start",
            "end",
            "created",
            "modified",
            "last_comment_date",
        ]:
            value = self.toLocalizedTime(value, long_format=1)

        return {
            # 'title': _(fieldname, default=fieldname),
            "value": value
        }

    def is_event(self, obj):
        if getattr(obj, "getObject", False):
            obj = obj.getObject()
        return IEvent.providedBy(obj)

    def formatted_date(self, item):
        provider = getMultiAdapter(
            (self.context, self.request, self), IContentProvider, name="formatted_date"
        )
        return provider(item)

    @property
    @memoize
    def album_images(self):
        """Get all images within this folder."""
        provides = [
            IImage.__identifier__,
            ILeadImage.__identifier__,
        ]
        images = self.results(batch=False, object_provides=provides)
        return images

    @property
    @memoize
    def album_folders(self):
        """Get all folders within this folder."""
        images = self.results(batch=False, object_provides=IFolder.__identifier__)
        return images

    @property
    def album_random_image(self):
        """Get random image from this folder."""
        img = None
        images = self.album_images
        if images:
            img = random.choice(images)
        return img

    @property
    def album_number_images(self):
        """Get number of images from this folder."""
        images = self.album_images
        return len(images)

    @property
    def no_items_message(self):
        return _(
            "description_no_items_in_folder",
            default="There are currently no items in this folder.",
        )

    @memoize
    def get_thumb_scale_table(self):
        if getattr(self.context, "suppress_thumbs", False):
            return None
        thsize = getattr(self.context, "thumb_scale_table", None)
        if thsize:
            return thsize
        registry = getUtility(IRegistry)
        settings = registry.forInterface(ISiteSchema, prefix="plone", check=False)
        if settings.no_thumbs_tables:
            return None
        return settings.thumb_scale_table

    @memoize
    def get_thumb_scale_list(self):
        if getattr(self.context, "suppress_thumbs", False):
            return None
        thsize = getattr(self.context, "thumb_scale_list", None)
        if thsize:
            return thsize
        registry = getUtility(IRegistry)
        settings = registry.forInterface(ISiteSchema, prefix="plone", check=False)
        if settings.no_thumbs_lists:
            return None
        return settings.thumb_scale_listing

    @memoize
    def get_thumb_scale_summary(self):
        if getattr(self.context, "suppress_thumbs", False):
            return None
        thsize = getattr(self.context, "thumb_scale_summary", None)
        if thsize:
            return thsize
        registry = getUtility(IRegistry)
        settings = registry.forInterface(ISiteSchema, prefix="plone", check=False)
        if settings.no_thumbs_summary:
            return None
        return settings.thumb_scale_summary

    def show_icons(self):
        return not getattr(self.context, "suppress_icons", False)
