from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.db.models import Q
from rest_framework_jwt.settings import api_settings


User = get_user_model()
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


class UserDetailSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()
    token = serializers.SerializerMethodField()
    roles = serializers.SerializerMethodField()
    avatar = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = [
            'username',
            'name',
            'email',
            'roles',
            'introduction',
            'avatar',
            'token'
        ]

    def get_name(self, obj):
        return obj.username

    def get_token(self, obj):
        return obj.username

    def get_roles(self, obj):
        return obj.role.split()

    def get_avatar(self, obj):
        return obj.get_image_url()


class UserLoginSerializer(serializers.ModelSerializer):
    token = serializers.CharField(allow_blank=True, read_only=True)
    username = serializers.CharField(required=False, allow_blank=True)
    # email = serializers.EmailField(required=False, allow_blank=True)

    class Meta:
        model = User
        fields = [
            'username',
            # 'email',
            'password',
            'token'
        ]

        extra_kwargs = {
            'password': {
                'write_only': True
            }
        }

    def validate(self, data):
        user_obj = None
        username = data.get('username', None)
        # email = data.get('email', None)
        password = data.get('password', None)

        # if not email and not username:
        #     raise serializers.ValidationError('username or email is required to login.')
        # user = User.objects.filter(
        #     Q(username=username) |
        #     Q(email=email)
        # ).distinct()
        if not username:
            raise serializers.ValidationError('username or email is required to login.')
        user = User.objects.filter(
                Q(username=username) |
                Q(email=username)
            ).distinct()
        user = user.exclude(email__isnull=True).exclude(email__iexact='')
        if user.exists() and user.count() == 1:
            user_obj = user.first()
        else:
            raise serializers.ValidationError('This username/email is not valid.')

        if user_obj:
            payload = jwt_payload_handler(user_obj)
            token = jwt_encode_handler(payload)
            if not user_obj.check_password(password):
                raise serializers.ValidationError('Incorrect credentials pls try again.')
            data['token'] = token

        return data
