# pylint: disable=I0011

""" This module holds the serializers of the ``brainstormers`` app. """

from mtp.apps.brainstormers.constants import GROUP, MODULE, PREVIEW
from mtp.apps.brainstormers.models import (
    DEFAULT_GROUP_ATTRIBUTES,
    Brainstormer,
    BrainstormerActivity,
    BrainstormerProposition,
    BrainstormerPropositionGroup,
    BrainstormerTemplate
)
from mtp.apps.trainings.models import TrainingSession

from rest_framework import serializers
from rest_framework.exceptions import ParseError


class BrainstormerActivitySerializer(serializers.ModelSerializer):
    """
    Serializer for ``brainstormers.BrainstormerActivity`` objects.
    """

    class Meta:
        model = BrainstormerActivity
        fields = ('id', 'name', 'preview', 'image',
                  'hash_preview', 'hash_image', 'trainings')


class BrainstormerTemplateSerializer(serializers.ModelSerializer):
    """
    Serializer for ``brainstormers.BrainstormerTemplate`` objects.
    """

    class Meta:
        model = BrainstormerTemplate
        fields = ('id', 'title', 'activity', 'training')


class BrainstormerPropositionSerializer(serializers.ModelSerializer):
    """
    Serializer for ``brainstormers.BrainstormerProposition`` objects.
    """

    group = serializers.PrimaryKeyRelatedField(
        queryset=BrainstormerPropositionGroup.objects.filter(is_deleted=False),
        required=False
    )

    class Meta:
        model = BrainstormerProposition
        fields = ('id', 'text', 'group', 'user')

    def create(self, validated_data):
        try:
            group = validated_data.pop('group')
        except KeyError:

            # No group was given in parameters, so we get or create a default
            # one in the brainstormer specified in the url.
            brainstormer_id = self.context.get('view').kwargs.get('parent_lookup_group'
                                                                  '__brainstormer')
            brainstormer = Brainstormer.objects.get(id=brainstormer_id)
            group, __ = BrainstormerPropositionGroup.objects.get_or_create(
                brainstormer=brainstormer, **DEFAULT_GROUP_ATTRIBUTES)

        except Brainstormer.DoesNotExist:
            raise ParseError("brainstormer_id incorrect : object does not exist")

        return BrainstormerProposition.objects.create(group=group, **validated_data)


class BrainstormerPropositionGroupSerializer(serializers.ModelSerializer):
    """
    Serializer for ``brainstormers.BrainstormerPropositionGroup`` objects.

    """

    brainstormer = serializers.PrimaryKeyRelatedField(read_only=True)
    propositions = BrainstormerPropositionSerializer(many=True, read_only=True)
    order = serializers.IntegerField(source='sort_order', required=False)  # For iOS compatibility
    x = serializers.DecimalField(  # pylint: disable=invalid-name
        max_digits=6,
        decimal_places=2,
        source='coord_x',  # For iOS compatibility
        required=False
    )
    y = serializers.DecimalField(  # pylint: disable=invalid-name
        max_digits=6,
        decimal_places=2,
        source='coord_y',  # For iOS compatibility
        required=False
    )

    class Meta:
        model = BrainstormerPropositionGroup
        fields = ('id', 'name', 'brainstormer', 'color',
                  'x', 'y', 'order', 'propositions')

    def create(self, validated_data):
        brainstormer_id = self.context.get('view').kwargs.get('parent_lookup_brainstormer')

        try:
            brainstormer = Brainstormer.objects.get(id=brainstormer_id)
        except Brainstormer.DoesNotExist:
            raise ParseError("brainstormer_id incorrect : object does not exist")

        return BrainstormerPropositionGroup.objects.create(
            brainstormer=brainstormer, **validated_data
        )


class BrainstormerSerializer(serializers.ModelSerializer):
    """
    Serializer for ``brainstormers.Brainstormer`` objects.
    """

    preview = serializers.SerializerMethodField(read_only=True)
    module = serializers.SerializerMethodField(read_only=True)
    groups = serializers.SerializerMethodField(read_only=True)
    order = serializers.IntegerField(source="sort_order", required=False)  # For iOS compatibility
    proposals = BrainstormerPropositionSerializer(
        source="get_propositions", many=True, read_only=True
    )
    proposal_groups = BrainstormerPropositionGroupSerializer(
        source="get_groups", many=True, read_only=True
    )
    training_session = serializers.PrimaryKeyRelatedField(
        source="session",
        queryset=TrainingSession.objects.non_deleted()
    )
    title = serializers.CharField(source="name")

    class Meta:
        model = Brainstormer
        fields = ('id', 'title', 'training_session',
                  'preview', 'module', 'groups', 'order', 'activity',
                  'proposals', 'proposal_groups')

    @staticmethod
    def get_preview(obj):  # pylint: disable=unused-argument
        """Return the PREVIEW constant value."""

        return PREVIEW

    @staticmethod
    def get_module(obj):  # pylint: disable=unused-argument
        """Return the MODULE constant value."""

        return MODULE

    @staticmethod
    def get_groups(obj):  # pylint: disable=unused-argument
        """Return the GROUP constant value."""

        return GROUP
