"""This module holds the QuerySets and the Managers for the ``assessments`` app."""

import logging

from django.db import models

from mtp.apps.sync.managers import SyncableQuerySet

from mtp.discrete_apps.versionable.managers import (
    DependencyManager,
    DependencyQuerySet,
    VersionableManager,
    VersionableQuerySet,
)

logger = logging.getLogger('mtp.apps.assessments')


class CompetencyTreeQuerySet(SyncableQuerySet, VersionableQuerySet):
    """
    QuerySet for the ``mtp.apps.assessments.models.competencies.CompetencyTree`` model.

    """

    def annotate_can_translate(self, user):
        """Annotate the ``QuerySet`` with a ``can_translate`` flag

        A ``CompetencyTree`` may only be translated by the manager of the ``business_unit``
        associated with it.

        Parameters
        ----------
        user: ``mtp.apps.accounts.models.MTPUser`` instance
            The user we want to annotate the ``QuerySet`` with

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

        """

        return self.annotate(
            can_translate=models.Case(
                models.When(
                    group__pk__in=user.managed_groups.values_list('pk', flat=True),
                    then=models.Value(True)
                ),
                default=models.Value(False),
                output_field=models.BooleanField(),
            )
        )

    def annotate_can_edit(self, user):
        """Annotate the ``QuerySet`` with a ``can_edit`` flag

        A ``CompetencyTree`` may only be edited by the manager of the ``job_profile``
        associated with it.

        Parameters
        ----------
        user: ``mtp.apps.accounts.models.MTPUser`` instance
            The user we want to annotate the ``QuerySet`` with

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

        """

        return self.annotate(
            can_edit=models.Case(
                models.When(
                    job_profile__pk__in=user.managed_groups.values_list('pk', flat=True),
                    then=models.Value(True)
                ),
                default=models.Value(False),
                output_field=models.BooleanField(),
            )
        )


class CompetencyTreeManager(VersionableManager.from_queryset(CompetencyTreeQuerySet)):
    """Manager used by the ``CompetencyTree`` model"""

    def get_for_session(self, session):
        """Get the competency tree associated to this training session.

        Parameters
        ----------
        session : ``mtp.apps.trainings.TrainingSession`` instance

        Returns
        -------
        instance of ``mtp.apps.assessments.models.competencies.CompetencyTree``
            or None if one cannot be fetched.

        """

        job_profile = session.training.job_profile

        tree = self.get_for_job_profile(job_profile)

        if tree:
            tree._session = session

        return tree

    def get_for_job_profile(self, job_profile):
        """Get the competency tree associated to this job_profile.

        Parameters
        ----------
        job_profile : Group

        Returns
        -------
        CompetencyTree
            The wanted tree or None if one cannot be fetched.

        """

        from mtp.apps.assessments.models import CompetencyTree

        try:
            return self.get(job_profile=job_profile, original_version=None)
        except (CompetencyTree.DoesNotExist, CompetencyTree.MultipleObjectsReturned):
            logger.exception("No competency tree for job profile %s", job_profile)
            return None


class CompetencyTreeUserScoreManager(models.Manager):
    """
    Manager for the ``mtp.apps.assessments.models.competencies.CompetencyTreeUserScore`` model.

    """
    pass


class CompetencyTreeUserScoreQuerySet(models.QuerySet):
    """
    QuerySet for the ``mtp.apps.assessments.models.competencies.CompetencyTreeUserScore`` model.

    """
    pass


class CompetencyQuerySet(SyncableQuerySet, DependencyQuerySet):
    """
    QuerySet for the ``mtp.apps.assessments.models.competencies.Competency`` model.

    """
    pass


class CompetencyManager(DependencyManager.from_queryset(CompetencyQuerySet)):
    """
    Manager for the ``mtp.apps.assessments.models.competencies.Competency`` model.

    """
    pass


class CompetencyUserScoreManager(models.Manager):
    """
    Manager for the ``mtp.apps.assessments.models.competencies.CompetencyUserScore`` model.

    """
    pass


class CompetencyUserScoreQuerySet(models.QuerySet):
    """
    QuerySet for the ``mtp.apps.assessments.models.competencies.CompetencyUserScore`` model.

    """
    pass


class DimensionQuerySet(SyncableQuerySet, DependencyQuerySet):
    """
    QuerySet for the ``mtp.apps.assessments.models.competencies.Dimension`` model.

    """
    pass


class DimensionManager(DependencyManager.from_queryset(DimensionQuerySet)):
    """
    Manager for the ``mtp.apps.assessments.models.competencies.Dimension`` model.

    """
    pass


class DimensionUserScoreManager(models.Manager):
    """
    Manager for the ``mtp.apps.assessments.models.competencies.DimensionUserScore`` model.

    """
    pass


class DimensionUserScoreQuerySet(models.QuerySet):
    """
    QuerySet for the ``mtp.apps.assessments.models.competencies.DimensionUserScore`` model.

    """
    pass
