from django.core.validators import MinValueValidator, MaxValueValidator
from rest_framework import serializers

from institute.serializers import InstituteSerializerForExamAndInstituteAndQuestionBank, \
    ListInstituteSerializerForCollaboratorsAndQuestionBank
from question_bank import conf
from utils import validators as main_validators
from utils.utils import compress_image
from utils.validators import IncludeExcludeOnlyValidator
from .models import QuestionBank, QuestionBankDefaultIcon
############################## API Serializers ##############################
from .utils import filters_template_validator
from .validetors import question_bank_sort_by_validator


class CreateQuestionBankInputSerializer(serializers.Serializer):
    context_institute_id = serializers.UUIDField()
    name = serializers.CharField()
    description = serializers.CharField(max_length=3000, required=False)
    public = serializers.BooleanField()
    icon = serializers.ImageField(required=False)
    default_icon_id = serializers.CharField(
        validators=[main_validators.uuid_validator], required=False)

    def validate_icon(self, value):
        main_validators.image_validetor(image=value, image_size_as_MB=conf.maximum_size_for_question_bank_icon_MG,
                                        format=conf.allowed_formats_for_question_bank_icon,
                                        max_side=conf.maximum_side_size_for_question_bank_icon)

        compress = compress_image(
            value, max_side_size=conf.maximum_side_size_compress_for_question_bank_icon)
        return compress

    def validate_name(self, value):
        main_validators.name_validator(
            name=value, min_length=3, max_length=100)
        return value


class EditQuestionBankInputSerializer(serializers.Serializer):
    token = serializers.CharField(max_length=460, required=False)
    api_key = serializers.CharField(max_length=460, required=False)
    question_bank_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    name = serializers.CharField(required=False)
    description = serializers.CharField(
        max_length=3000, required=False, allow_null=True, allow_blank=True)
    public = serializers.BooleanField(required=False)
    icon = serializers.ImageField(required=False)
    default_icon_id = serializers.CharField(
        validators=[main_validators.uuid_validator], required=False)

    def validate_icon(self, value):
        main_validators.image_validetor(image=value, image_size_as_MB=conf.maximum_size_for_question_bank_icon_MG,
                                        format=conf.allowed_formats_for_question_bank_icon,
                                        max_side=conf.maximum_side_size_for_question_bank_icon)
        compress = compress_image(
            value, max_side_size=conf.maximum_side_size_compress_for_question_bank_icon)
        return compress

    def validate_name(self, value):
        main_validators.name_validator(
            name=value, min_length=3, max_length=100)
        return value


class EditQuestionBankFiltersInputSerializer(serializers.Serializer):
    token = serializers.CharField(max_length=460, required=False)
    api_key = serializers.CharField(max_length=460, required=False)
    question_bank_id = serializers.CharField(validators=[main_validators.uuid_validator])
    filters_template = serializers.JSONField(validators=[filters_template_validator])


class ArchiveQuestionBankInputSerializer(serializers.Serializer):
    question_bank_id = serializers.UUIDField()
    context_institute_id = serializers.UUIDField()


class UnsubscribeQuestionBankInputSerializer(serializers.Serializer):
    question_bank_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    context_institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])


class GetQuestionBankInputSerializer(serializers.Serializer):
    token = serializers.CharField(max_length=460, required=False)
    api_key = serializers.CharField(max_length=460, required=False)
    question_bank_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    context_institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])


class QuestionBankListInputSerializer(serializers.Serializer):
    context_institute_id = serializers.CharField(validators=[main_validators.uuid_validator])
    skip = serializers.IntegerField(validators=[MinValueValidator(0)])
    take = serializers.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(100)])
    q = serializers.CharField(max_length=100, required=False, allow_null=True)
    sort_by = serializers.CharField(validators=[question_bank_sort_by_validator])
    archived_filter = serializers.CharField(validators=[IncludeExcludeOnlyValidator()])


class TagsListOfAQuestionBankInputSerializer(serializers.Serializer):
    token = serializers.CharField(max_length=460, required=False)
    api_key = serializers.CharField(max_length=460, required=False)
    question_bank_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    context_institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])


class TagsKeysListOfAQuestionBankInputSerializer(serializers.Serializer):
    token = serializers.CharField(max_length=460, required=False)
    api_key = serializers.CharField(max_length=460, required=False)
    question_bank_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    context_institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    skip = serializers.IntegerField(validators=[MinValueValidator(0)])
    take = serializers.IntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(100)])
    q = serializers.CharField(max_length=100, required=False, allow_null=True)


class TagsValuesListOfAQuestionBankInputSerializer(serializers.Serializer):
    token = serializers.CharField(max_length=460, required=False)
    api_key = serializers.CharField(max_length=460, required=False)
    question_bank_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    context_institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    key = serializers.CharField(max_length=50)
    skip = serializers.IntegerField(validators=[MinValueValidator(0)])
    take = serializers.IntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(100)])
    q = serializers.CharField(max_length=100, required=False, allow_null=True)


############################## Model Serializers ##############################


class QuestionBankModelSerializer(serializers.ModelSerializer):
    institute = InstituteSerializerForExamAndInstituteAndQuestionBank()
    picked = serializers.SerializerMethodField(method_name='get_picked')

    def get_picked(self, instance):
        if self.context.get("context_institute"):
            return self.context.get("context_institute").question_bank_is_picked(instance.id)
        else:
            return None

    class Meta:
        model = QuestionBank
        fields = ['id', 'name', 'institute', 'description', 'picked', 'price',
                  'questions_count', 'accessibility', 'rates', 'archived', 'icon', 'poster', 'featured', 'modified_at',
                  'created_at']


class QuestionBankGetSerializer(serializers.ModelSerializer):
    institute = InstituteSerializerForExamAndInstituteAndQuestionBank()
    picked = serializers.SerializerMethodField(method_name='get_picked')
    filters = serializers.SerializerMethodField(method_name='get_filters')
    tags = serializers.SerializerMethodField(method_name='get_tags')

    def get_picked(self, instance):
        if self.context.get("context_institute"):
            return self.context.get("context_institute").question_bank_is_picked(instance.id)
        else:
            return None

    def get_filters(self, instance):
        return instance._filters

    def get_tags(self, instance):
        return instance._tags

    class Meta:
        model = QuestionBank
        fields = ['id', 'name', 'institute', 'description', 'picked', 'filters', 'tags', 'price', 'filters_template',
                  'questions_count', 'accessibility', 'rates', 'archived', 'icon', 'poster', 'featured', 'modified_at',
                  'created_at']


class QuestionBankforPickedQuestionBankListSerializer(serializers.ModelSerializer):
    institute = InstituteSerializerForExamAndInstituteAndQuestionBank()

    class Meta:
        model = QuestionBank
        fields = ['id', 'name', 'institute', 'description', 'price',
                  'questions_count', 'accessibility', 'rates', 'archived', 'icon', 'poster', 'featured', 'modified_at',
                  'created_at']


# class QuestionBankAccessibilityModelSerializer(serializers.ModelSerializer):
#     question_bank = QuestionBankforPickedQuestionBankListSerializer()

#     class Meta:
#         model = QuestionBankAccessibility
#         fields = ['question_bank', 'type',
#                   'created_at']

#     def to_representation(self, instance):
#         data = super().to_representation(instance)
#         question_bank = data.pop('question_bank')
#         question_bank['relation'] = data['type']
#         question_bank['picked'] = True
#         return question_bank


class BookMarkQuestionBankPublicInputSerializer(serializers.Serializer):
    question_bank_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    star = serializers.BooleanField(required=True)


class ListQuestionBankSerializer(serializers.ModelSerializer):
    institute = ListInstituteSerializerForCollaboratorsAndQuestionBank()

    class Meta:
        model = QuestionBank
        fields = ['id', 'name', 'institute', 'description', 'price',
                  'questions_count', 'accessibility', 'rates', 'archived', 'icon', 'poster', 'featured', 'modified_at',
                  'created_at']


class QuestionBankMarketPlaceInputSerializer(serializers.Serializer):
    skip = serializers.IntegerField(validators=[MinValueValidator(0)])
    take = serializers.IntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(100)])
    q = serializers.CharField(required=False)
    featured_filter = serializers.CharField(validators=[IncludeExcludeOnlyValidator()])
    free_filter = serializers.CharField(validators=[IncludeExcludeOnlyValidator()])
    context_institute_id = serializers.CharField(validators=[main_validators.uuid_validator])


class QuestionBankMarketPlaceModelSerializer(serializers.ModelSerializer):
    institute = InstituteSerializerForExamAndInstituteAndQuestionBank()
    picked = serializers.SerializerMethodField('fetch_picked')

    # poster = serializers.SerializerMethodField()
    # icon = serializers.SerializerMethodField()

    def fetch_picked(self, obj):
        return obj.picked

    class Meta:
        model = QuestionBank
        fields = ['id', 'picked', 'name', 'institute', 'description', 'price',
                  'questions_count', 'accessibility', 'rates', 'archived', 'icon', 'poster', 'featured', 'modified_at',
                  'created_at']

    # def get_poster(self, instance):
    #     if instance.poster and hasattr(instance.poster, 'url'):
    #         request = self.context.get('request')
    #         return request.build_absolute_uri(instance.poster.url)
    #     else:
    #         return instance.poster
    #
    # def get_icon(self, instance):
    #     if instance.icon and hasattr(instance.icon, 'url'):
    #         request = self.context.get('request')
    #         return request.build_absolute_uri(instance.icon.url)
    #     else:
    #         return instance.icon


class QuestionBankPickInputSerializer(serializers.Serializer):
    question_bank_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    context_institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])


class QuestionBankDefaultIconsListModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = QuestionBankDefaultIcon
        fields = ('id', 'icon')
