"""This module holds the forms for the ``trainings`` app."""

from django import forms
from django.utils.translation import ugettext_lazy as _

import waffle

from mtp.apps.accounts.constants import GROUPTYPE_BUSINESS_UNIT
from mtp.apps.accounts.forms import MTPUserSelectMultipleWidget
from mtp.apps.accounts.models import Group, MTPUser

from .models import Training, TrainingClientOptions, TrainingSession


def _toggle_locks(fields):
    """
    Remove ``*_lock`` fields from the ``TrainingForm`` according to the
    ``enable_training_locks`` Waffle switch.

    """
    if not waffle.switch_is_active('enable_training_locks'):
        lock_fields = [field for field in fields if field.endswith('_lock')]
        for lock_field in lock_fields:
            del fields[lock_field]


class TrainingForm(forms.ModelForm):
    """Form for ``mtp.apps.trainings.models.Training`` model."""

    class Meta:
        model = Training
        fields = [
            'name',
            'description',
            'theme',
            'job_profile',
            'business_unit',
            'thumbnail_image',
            'header_image',
            '_external_id',
        ]

    def __init__(self, *args, **kwargs):
        """Init the form accordingly to the provided kwargs

        Parameters
        ----------
        kwargs: dict
            - current_user: ``mtp.apps.accounts.models.MTPUser`` instance
                Used to filter the available groups for the business_unit field.

        """

        current_user = kwargs.pop('current_user')

        super().__init__(*args, **kwargs)

        # Make sure there's no empty choice in the theme selector.
        if 'theme' in self.fields:
            self.fields['theme'].empty_label = None

        # If assessment is disabled, we remove the `job_profile` field
        if not waffle.switch_is_active('enable_assessments'):
            self.fields.pop('job_profile')
        else:

            # Filter the job_profile which can be added
            self.fields['job_profile'].queryset = Group.objects.job_profiles().non_deleted().filter(
                member_roles__user=current_user
            )

            # Filter the groups that can be added,
            # accordingly to the user's managed groups
            self.fields['business_unit'].queryset = Group.objects.filter(
                member_roles__user=current_user,
                type__name=GROUPTYPE_BUSINESS_UNIT
            )

        # disabled _external_id edition when editing
        self.fields['_external_id'].widget.attrs['disabled'] = True


class TrainingCreateForm(TrainingForm):
    """Form for ``mtp.apps.trainings.models.Training`` model creation."""

    def __init__(self, *args, **kwargs):
        """Init the form accordingly to the provided kwargs"""

        super().__init__(*args, **kwargs)

        # enable _external_id edition when creating
        self.fields['_external_id'].widget.attrs['disabled'] = False


class TrainingArchiveForm(forms.ModelForm):
    """Form for archiving a ``Training`` instance

    Attributes
    ----------
    current_user: MTPUser
        The user asking for the archiving.

    For the other parameters, see ``django.forms.ModelForm``

    """

    archive_children = forms.BooleanField(required=False)

    class Meta:
        model = Training
        fields = (
            'archive_children',
        )

    def __init__(self, current_user, *args, **kwargs):
        """Populate the label of the ``archive_children`` field

        If the training doesn't have any children, drop the field.

        """

        super().__init__(*args, **kwargs)

        duplicates_ids_nb = len(Training.objects.get_duplicate_ids(
            [self.instance.id],
            exclude_owner_id=current_user.id
        ))

        if duplicates_ids_nb:
            self.fields['archive_children'].label = _(
                'Archive the shared trainings (%d shared trainings will also be archived)' % (
                    duplicates_ids_nb
                )
            )
        else:
            self.fields.pop('archive_children')


class TrainingSessionForm(forms.ModelForm):
    """Form for ``mtp.apps.trainings.models.TrainingSession`` model."""

    AVAILABLE_PERMISSION_CHOICES = TrainingSession.PERMISSION_CHOICES.extract_subset(
        'PUBLIC', 'PRIVATE',
    )

    users = forms.ModelMultipleChoiceField(
        widget=MTPUserSelectMultipleWidget(
            attrs={'data-allow-clear': 'false'},
        ),
        required=False,
        queryset=MTPUser.objects.non_deleted().active().trainees(),
        label=_('Users')
    )

    class Meta:
        model = TrainingSession
        fields = (
            'training',
            'trainer',
            'users',
            'start_date',
            'end_date',
            'permissions',
        )

    def __init__(self, *args, **kwargs):
        """Init the form accordingly to the provided kwargs

        Parameters
        ----------
        kwargs: dict
            - remove_training_field: bool
                If ``True``, the training field is removed.
            - remove_trainer_field: bool
                If ``True``, the trainer field is removed.
            - current_user: ``mtp.apps.accounts.models.MTPUser`` instance
                Used to filter the trainings which can be used in the
                training field.

        """

        remove_training_field = kwargs.pop('remove_training_field')
        remove_trainer_field = kwargs.pop('remove_trainer_field')
        current_user = kwargs.pop('current_user')

        super().__init__(*args, **kwargs)

        self.fields['permissions'].choices = self.AVAILABLE_PERMISSION_CHOICES

        if remove_training_field:
            self.fields.pop('training')
        else:
            self.fields['training'].queryset = Training.objects.available_for_user(
                current_user
            )

        if remove_trainer_field:
            self.fields.pop('trainer')
        else:
            self.fields['trainer'].queryset = MTPUser.objects.non_deleted().active().trainers()


class TrainingOptionsForm(forms.ModelForm):
    """Form for ``TrainingClientOptions`` model."""

    class Meta:
        model = TrainingClientOptions
        fields = (
            'activate_show_results',
            'activate_activity_quickcreation',
            'activate_qrcode_launcher',
        )

    def __init__(self, *args, **kwargs):
        """Adapt the form according to assessment waffle.

        For the parameters, see ``django.forms.ModelForm``"""

        super().__init__(*args, **kwargs)

        if not waffle.switch_is_active('enable_assessments'):
            self.fields.pop('activate_show_results')
