from rest_framework import serializers
from fb.quizz.models import Quizz, QuizzGroup, QuizzQuestion, QuizzQuestionAnswer, PersonAnswer
from fb.staff.models import Group, Person
from fb.staff import serializers as staff

from operator import attrgetter

class QuizzGroupSerializer(serializers.ModelSerializer):

    group_id = serializers.IntegerField()
    group = staff.GroupSerializer(many=False, read_only=True)

    def validate(self, data):
        group_id = data.get('group_id')
        try:
            Group.objects.get(staff_id=group_id)
        except Group.DoesNotExist:
            raise serializers.ValidationError('Group with staff_id %s does not exist.' % group_id)
        return data

    class Meta:
        model = QuizzGroup
        exclude = ('quizz',)


class QuizzQuestionAnswerSerializer(serializers.ModelSerializer):

    question_type = serializers.CharField(source='question.question_type', read_only=True)
    question_text = serializers.CharField(source='question.text', read_only=True)

    def validate(self, data):
        try:
            is_open = bool(data.get('is_open', False))
        except ValueError:
            is_open = False
        if not is_open and 'text' not in data:
            raise serializers.ValidationError('Text is required value for not open answers')
        return data


    class Meta:
        model = QuizzQuestionAnswer
        exclude = ('question',)


class QuizzQuestionSerializer(serializers.ModelSerializer):

    answers = QuizzQuestionAnswerSerializer(many=True, allow_add_remove=True, source='quizzquestionanswer_set', default=[])

    def validate(self, data):
        try:
            question_type = int(data.get('question_type', QuizzQuestion.QT_CHECKBOX))
        except ValueError:
            question_type = QuizzQuestion.QT_CHECKBOX
        if (question_type == QuizzQuestion.QT_COMPETENCE
            and 'quizzquestionanswer_set' in data
        ):
            data['quizzquestionanswer_set'] = filter(attrgetter('is_open'), data['quizzquestionanswer_set'])
        return data

    def restore_object(self, attrs, instance=None):
        if instance is not None and 'question_type' in attrs:
            old_question_type_element = QuizzQuestion.get_question_type_element(instance.question_type)
            new_question_type_element = QuizzQuestion.get_question_type_element(attrs['question_type'])
            if old_question_type_element != new_question_type_element:
                del attrs['question_type']
        return super(QuizzQuestionSerializer, self).restore_object(attrs, instance)

    class Meta:
        model = QuizzQuestion
        exclude = ('quizz',)


class QuizzQuestionWithPersonAnswerSerializer(QuizzQuestionSerializer):
    def to_native(self, instance):
        ret = super(QuizzQuestionWithPersonAnswerSerializer, self).to_native(instance)
        if hasattr(self, 'context') and 'person' in self.context:
            answers = PersonAnswer.objects.filter(
                on_whom=self.context['person'],
                quizz_answer__question=instance,
            ).select_related(
                'on_whom',
                'person',
            )
            # well, this is fucked up serializers mess should be
            # rewritten anyway
            # for now we just fixing a bug when answers collected without
            # consideration of feedbacks filtered by date
            feedback_ids = self.context.get('filtered_feedback_ids')
            if feedback_ids:
                answers = answers.filter(feedback_id__in=feedback_ids)
            ret['person_answers'] = PersonAnswerSerializer(
                instance=answers,
                many=True,
            ).data
        else:
            ret['person_answers'] = []
        return ret


class QuizzSerializer(serializers.ModelSerializer):

    groups = QuizzGroupSerializer(many=True, allow_add_remove=True, source='quizzgroup_set', default=[])
    questions = QuizzQuestionSerializer(many=True, allow_add_remove=True, source='quizzquestion_set', default=[])
    owner = staff.PersonSerializer(many=False, read_only=True)
    count_of_answers = serializers.IntegerField(read_only=True)

    def validate(self, data):
        is_published = data.get('is_published')
        if not is_published:
            return data
        # Validate departments is not empty list
        groups = data.get('quizzgroup_set')
        if not groups:
            raise serializers.ValidationError('Groups is empty')
        # Validate questions is not empty list
        questions = data.get('quizzquestion_set')
        if not questions:
            raise serializers.ValidationError('Questions is empty')
        for question in questions:
            if not question.text:
                raise serializers.ValidationError('Question without text')
            if not question.description:
                raise serializers.ValidationError('Question without description')

        return data


    class Meta:
        model = Quizz


class PersonAnswerSerializer(serializers.ModelSerializer):

    feedback = serializers.IntegerField(source='feedback_id', required=False)
    person = staff.PersonSerializer(read_only=True)
    person_id = serializers.IntegerField()
    on_whom = staff.PersonSerializer(read_only=True)
    on_whom_id = serializers.IntegerField()
    quizz_answer = QuizzQuestionAnswerSerializer(read_only=True)
    quizz_answer_id = serializers.IntegerField()
    text = serializers.CharField()

    class Meta:
        model = PersonAnswer

    def from_native(self, data, files):
        if 'request' in self.context:
            person_uid = self.context['request'].yauser.uid
            person = Person.objects.get(uid=person_uid)
            data['person_id'] = person.staff_id
        return super(PersonAnswerSerializer, self).from_native(data, files)
