from copy import deepcopy
from functools import cached_property
from logging import getLogger
from operator import itemgetter
from plone import api
from plone.app.querystring import queryparser
from plone.app.querystring.interfaces import IParsedQueryIndexModifier
from plone.app.querystring.interfaces import IQueryModifier
from ploneintranet.imagebank.browser.base import ImageBankBaseView
from zope.component import getUtilitiesFor

logger = getLogger(__name__)


class ImageBankCollectionView(ImageBankBaseView):

    def can_upload(self) -> bool:
        """We cannot upload to a collection"""
        return False

    @cached_property
    def title(self):
        """This returns the title translated to the current language,
        if a matching message id is found, otherwise it returns the original title.
        """
        return api.content.translate(self.context.title, domain="ploneintranet")

    @cached_property
    def base_query(self) -> dict:
        """Parse the query defined in the collection and return a dictionary
        that can will be used as to query the catalog.

        The code is a stripped down version of the one you can find in
        plone.app.querystring.querybuilder.QueryBuilder._makequery
        """
        query = deepcopy(self.context.query)
        query_modifiers = getUtilitiesFor(IQueryModifier)
        for name, modifier in sorted(query_modifiers, key=itemgetter(0)):
            query = modifier(query)

        sort_order = "descending" if self.context.sort_reversed else None
        parsedquery = queryparser.parseFormquery(
            self.context, query, self.context.sort_on, sort_order
        )
        index_modifiers = getUtilitiesFor(IParsedQueryIndexModifier)
        for name, modifier in index_modifiers:
            if name in parsedquery:
                new_name, query = modifier(parsedquery[name])
                parsedquery[name] = query
                # if a new index name has been returned, we need to replace
                # the native ones
                if name != new_name:
                    del parsedquery[name]
                    parsedquery[new_name] = query

        # Check for valid indexes
        catalog = api.portal.get_tool("portal_catalog")
        valid_indexes = [index for index in parsedquery if index in catalog.indexes()]

        # We'll ignore any invalid index, but will return an empty set if none
        # of the indexes are valid.
        if not valid_indexes:
            logger.warning("Using empty query because there are no valid indexes used.")
            parsedquery = {}

        return parsedquery
