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

from institute.models import Institute
from institute.serializers import ListInstituteSerializerForCollaboratorsAndQuestionBank
from utils import validators as main_validators
from collaborators.models import Access, InviteAccess
from collaborators import validators as collaborators_validators
from authenticate import serializers as authenticate_serializers, validators as authenticate_validators
from institute import validators as institute_validators


################################################################################
######################### APIs Serializers #####################################
################################################################################

class InviteInputSerializer(serializers.Serializer):
    """
    This serializer class takes institute_id, email & roles from user and passed it to
    InviteAPIView to do some works on it.
    """
    institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    email = serializers.CharField(max_length=254, validators=[authenticate_validators.email_validator], required=False)
    phone = serializers.CharField(max_length=15, validators=[authenticate_validators.phone_validator], required=False)
    roles = serializers.JSONField(validators=[collaborators_validators.roles_validator])

    def validate(self, data):
        authenticate_validators.make_email_or_phone_required_validator(data)
        return data


class ListInvitationInputSerializer(serializers.Serializer):
    institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    skip = serializers.IntegerField(validators=[MinValueValidator(0)])
    take = serializers.IntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(100)])


class ListMyInvitationInputSerializer(serializers.Serializer):
    skip = serializers.IntegerField(validators=[MinValueValidator(0)])
    take = serializers.IntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(100)])


class InstituteSerializerForCollaborators(serializers.ModelSerializer):
    owner = serializers.SerializerMethodField(method_name='owner_info')

    def owner_info(self, obj):
        return authenticate_serializers.UserSerializerForCollaborators().data
    class Meta:
        model = Institute
        fields = ['id', 'name', 'logo','sandbox', 'logo_thumbnail', 'poster', 'poster_thumbnail','owner']


class InvitationSerializer(serializers.ModelSerializer):
    institute = InstituteSerializerForCollaborators()

    class Meta:
        model = InviteAccess
        fields = ['id', 'institute', 'roles']


class AcceptInvitationInputSerializer(serializers.Serializer):
    """
    This serializer class takes key from user and passed it to
    AcceptInvitationAPIView to do some works on it.
    """
    invitation_id = serializers.CharField(
        validators=[main_validators.uuid_validator])


class RejectInvitationInputSerializer(serializers.Serializer):
    """
    This serializer class takes key from user and passed it to
    AcceptInvitationAPIView to do some works on it.
    """
    invitation_id = serializers.CharField(
        validators=[main_validators.uuid_validator])


class DeleteInvitationInputSerializer(serializers.Serializer):
    """
    This serializer class takes invited_access_id from user and passed it to
    DeleteInvitationAPIView to do some works on it.
    """
    invited_access_id = serializers.CharField(
        validators=[main_validators.uuid_validator])


class RemoveAccessInputSerializer(serializers.Serializer):
    """
    This serializer class takes access_id from user and passed it to
    RemoveAccessAPIView to do some works on it.
    """
    access_id = serializers.CharField(
        validators=[main_validators.uuid_validator])

class AllCollaboratorsInputSerializer(serializers.Serializer):
    """
    This serializer class takes institute_id, skip, take, sort_by & search_words from user and passed it to
    AllCollaboratorsAPIView to do some works on it.
    """
    institute_id = serializers.CharField()
    skip = serializers.IntegerField(validators=[MinValueValidator(0)])
    take = serializers.IntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(100)])
    search_words = serializers.CharField(required=False)


class LeaveCollaboratorInputSerializer(serializers.Serializer):
    institute_id = serializers.CharField(
        validators=[main_validators.uuid_validator])


################################################################################
######################### Models Serializers ###################################
################################################################################



class AccessibleInstituteSerializer(serializers.ModelSerializer):
    """
    This serializer class takes one or more Access records and serializes them to json with desired fields.
    """
    id = serializers.CharField(source='institute.id')
    name = serializers.CharField(source='institute_name')
    description = serializers.CharField(source='institute.description')
    logo = serializers.ImageField(source='institute.logo')
    sandbox = serializers.BooleanField(source='institute.sandbox')
    created_at = serializers.CharField(source='institute_created_at')
    owner = serializers.SerializerMethodField(method_name='owner_info')

    def owner_info(self, obj):
        return authenticate_serializers.UserSerializerForAuthenticateAndCollaboratorsAndInstitute(obj.institute.user).data

    class Meta:
        model = Access
        fields = ['id', 'name', 'description', 'logo',
                  'sandbox', 'created_at', 'roles', 'owner']


class AccessSerializerForAllCollabrators(serializers.ModelSerializer):
    user = authenticate_serializers.UserSerializerForCollaborators()
    class Meta:
        model = Access
        fields = ['id', 'user','roles']




class InvitationSerializer(serializers.ModelSerializer):
    institute = InstituteSerializerForCollaborators()
    modifire = authenticate_serializers.UserSerializerForCollaborators()
    """
    This serializer class takes one or more InviteAccess records and serializes them to json with desired fields.
    """
    class Meta:
        model = InviteAccess
        fields = ['id', 'roles','invited_email','invited_phone','institute','modifire']

class RemoveInvitationInputSerializer(serializers.Serializer):
    """
    This serializer class takes key from user and passed it to
    AcceptInvitationAPIView to do some works on it.
    """
    invitation_id = serializers.CharField(
        validators=[main_validators.uuid_validator])

class EditInvitationInputSerializer(serializers.Serializer):
    invitation_id = serializers.CharField(
        validators=[main_validators.uuid_validator])
    new_roles = serializers.JSONField(validators=[collaborators_validators.roles_validator])



class EditCollaboratorInputSerializer(serializers.Serializer):
    access_id = serializers.CharField(
        validators=[main_validators.uuid_validator])

    new_roles = serializers.JSONField(validators=[collaborators_validators.roles_validator])

