from .update_social import UpdateSocialBase
from networkx.exception import NetworkXError
from plone import api
from plone.memoize.view import memoize_contextless
from ploneintranet.layout.app import apps_container_id
from ploneintranet.userprofile.interfaces import IFunctionalPrincipal
from ploneintranet.workspace.config import INTRANET_USERS_GROUP_ID


class Users(UpdateSocialBase):
    _batch_size = 5

    @property
    def filters_groups(self):
        return {
            "portal_type": "ploneintranet.userprofile.workgroup",
            "-object_provides": IFunctionalPrincipal.__identifier__,
            "-Title": INTRANET_USERS_GROUP_ID,
        }

    @property
    def filters_users(self):
        return {
            "portal_type": "ploneintranet.userprofile.userprofile",
            "review_state": "enabled",
        }

    @property
    def query(self):
        return self.request.form.get("usersearch", "").strip()

    @property
    @memoize_contextless
    def pas_view(self):
        """The graph containing the relations between the principals managed by
        PAS."""
        return api.content.get_view("pas_view", self.context, self.request)

    @property
    @memoize_contextless
    def search_view(self):
        portal = api.portal.get()
        app = getattr(portal, apps_container_id).search
        return api.content.get_view("search_people", app, self.request)

    def is_group(self, item):
        return item.portal_type == "ploneintranet.userprofile.workgroup"

    def num_users(self, item):
        if not self.is_group(item):
            return None
        num = None
        try:
            num = len(self.pas_view.descendants(f"workgroup:{item.UID}"))
        except NetworkXError:
            # Ignore errors.
            pass
        return num

    def pas_uid(self, item):
        prefix = "userprofile"
        if item.portal_type == "ploneintranet.userprofile.workgroup":
            prefix = "workgroup"
        return f"{prefix}:{item.UID}"

    def title(self, item):
        return item.title or item.getId

    @property
    def groups(self):
        """Get the groups that match the search query."""
        search_util = self.search_view.search_util
        response = search_util.query(
            phrase=self.query,
            filters=self.filters_groups,
            start=0,
            step=self._batch_size,
            sort="sortable_title",
        )
        return response

    @property
    def users(self):
        """Get the users that match the search query.

        Users are sorted on fullname
        """
        search_util = self.search_view.search_util
        response = search_util.query(
            phrase=self.query,
            filters=self.filters_users,
            start=0,
            step=self._batch_size,
            sort="sortable_title",
        )
        return response

    @property
    def results(self):
        return list(self.groups) + list(self.users)
