"""This module holds the managers and QuerySets for the ``accounts`` app."""

from django.contrib.auth.models import UserManager
from django.db import models

from mtp.apps.sync.managers import SyncableQuerySet

from .constants import (
    GROUPTYPE_BUSINESS_UNIT,
    GROUPTYPE_INTERNAL,
    GROUPTYPE_JOB_PROFILE,
    INTERNAL_GROUP_TRAINER,
    INTERNAL_GROUP_TRAINEE
)


class GroupTypeQuerySet(SyncableQuerySet, models.QuerySet):
    """Base queryset class for ``GroupType``s."""

    def internal(self):
        """Return only internal group types.

        Returns
        -------
        Queryset of ``mtp.apps.accounts.models.GroupType``

        """
        return self.filter(name=GROUPTYPE_INTERNAL)

    def job_profiles(self):
        """Return only group types representing job profiles.

        Returns
        -------
        Queryset of ``mtp.apps.accounts.models.GroupType``

        """
        return self.filter(name=GROUPTYPE_JOB_PROFILE)



class GroupTypeManager(models.Manager):
    pass


class GroupManager(models.Manager):
    """
    The manager for the auth's Group model.

    """
    def get_by_natural_key(self, name):
        return self.get(name=name)


class GroupQuerySet(SyncableQuerySet, models.QuerySet):
    """QuerySet for the ``mtp.apps.accounts.models.Group`` model."""

    def is_training_filter(self):
        """Return only group who can be used as a training filter.

        Returns
        -------
        Queryset of ``mtp.apps.accounts.models.Group``

        """
        return self.filter(type__is_training_filter=True)

    def managed_by(self, user):
        """Filter the groups which are managed by the provided user

        Parameters
        ----------
        user : mtp.apps.accounts.models.MTPUser
            The user for whom we want the managed groups.

        Returns
        -------
        GroupQueryset
            A clone of the original queryset (``self``), annotated.

        """

        from .models import GroupRole

        return self.filter(
            member_roles__role=GroupRole.ROLES.MANAGER,
            member_roles__user=user
        )

    def business_units(self):
        """Return only group who are business units.

        Returns
        -------
        Queryset of ``mtp.apps.accounts.models.Group``

        """
        return self.filter(type__name=GROUPTYPE_BUSINESS_UNIT)

    def job_profiles(self):
        """Return only group who are job profiles.

        Returns
        -------
        Queryset of ``mtp.apps.accounts.models.Group``

        """
        return self.filter(type__name=GROUPTYPE_JOB_PROFILE)


class GroupRoleManager(models.Manager):
    """The manager for the ``GroupRole`` model."""

    pass


class MTPUserQuerySet(SyncableQuerySet, models.QuerySet):
    """QuerySet for the ``mtp.apps.accounts.models.MTPUser`` model."""

    def active(self):
        """Return only users who are active.

        Returns
        -------
        Queryset of ``mtp.apps.accounts.models.MTPUser``

        """

        return self.filter(is_active=True)

    def trainers(self):
        """Return only users who belongs to the trainer group.

        Returns
        -------
        Queryset of ``mtp.apps.accounts.models.MTPUser``

        """

        return self.filter(mgroups__name=INTERNAL_GROUP_TRAINER)

    def trainees(self):
        """Return only users who belongs to the trainee group.

        Returns
        -------
        Queryset of ``mtp.apps.accounts.models.MTPUser``

        """

        return self.filter(mgroups__name=INTERNAL_GROUP_TRAINEE)


class MTPUserManager(UserManager.from_queryset(MTPUserQuerySet)):
    """Manager for the ``mtp.apps.accounts.models.MTPUser`` model."""

    pass
