from collections import defaultdict
from collections import OrderedDict
from datetime import date
from plone import api
from plone.memoize.view import memoize
from plone.tiles import Tile
from ploneintranet.core import _
from ploneintranet.search.interfaces import ISiteSearch
from zope.component import getUtility

import logging

log = logging.getLogger(__name__)


class GroupedSearchTile(Tile):
    @property
    def _types_to_search_for(self):
        pu = api.portal.get_tool("plone_utils")
        all_types = set(pu.getUserFriendlyTypes())
        excluded = set(
            api.portal.get_registry_record(
                "ploneintranet.layout.types_not_listed_on_userprofile", default=[]
            )
        )
        return list(all_types - excluded)

    @memoize
    def search_results(self):
        search_util = getUtility(ISiteSearch)
        response = search_util.query(
            phrase=self.request.form.get("SearchableText", None),
            filters={
                "Creator": self.context.getId(),
                "portal_type": self._types_to_search_for,
            },
            step=9999,
        )
        return response

    @memoize
    def results_by_date(self):
        """Return the list of results grouped by date"""
        docs = defaultdict(list)
        today = date.today()

        for result in self.search_results():
            if hasattr(result.modified, "date"):
                day_past = (today - result.modified.date()).days
            else:
                day_past = 100
            if day_past < 1:
                docs[_("Today")].append(result)
            elif day_past < 7:
                docs[_("Last week")].append(result)
            elif day_past < 30:
                docs[_("Last month")].append(result)
            else:
                docs[_("All time")].append(result)
        for key in docs.keys():
            docs[key] = sorted(docs[key], key=lambda x: x.modified, reverse=True)
        return docs

    @memoize
    def results_by_letter(self):
        """Return the list of results grouped by letter"""
        docs = defaultdict(list)
        for result in self.search_results():
            stripped_title = result.title.strip()
            if stripped_title:
                key = stripped_title[0].upper()
            else:
                key = _("No title")
            docs[key].append(result)
        for key in docs.keys():
            docs[key] = sorted(docs[key], key=lambda x: x.title)
        return OrderedDict(sorted(docs.items()))

    @memoize
    def results_sorted_groups(self):
        """Return the groups"""
        group_by = self.request.get("group-by", "first-letter")
        if group_by == "first-letter":
            groups = sorted(self.results_by_letter().keys())
            if _("No title") in groups:
                no_title = groups.pop(groups.index(_("No title")))
                groups.append(no_title)
            return groups
        elif group_by == "date":
            return [_("Today"), _("Last week"), _("Last month"), _("All time")]

    @memoize
    def results_grouped(self):
        """Dispatch to the relevant method to group the results"""
        group_by = self.request.get("group-by", "first-letter")
        if group_by == "first-letter":
            return self.results_by_letter()
        elif group_by == "date":
            return self.results_by_date()
        return {}
