from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from core.models import UserInformation, UserApproval
from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from django.core.exceptions import ValidationError
from django.contrib.auth.password_validation import validate_password
from rest_framework.exceptions import ErrorDetail
from django.core.exceptions import ValidationError
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

# User._meta.get_field('email')._unique = True

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        username_or_email = attrs.get("username")
        user = User.objects.filter(email=username_or_email).first() or User.objects.filter(username=username_or_email).first()
        if not user:
            raise serializers.ValidationError({"error": "User not found. Please check the username or email."})
        try:
            approval = UserApproval.objects.get(user=user)
            if approval.approval_status != 'Approved':
                raise serializers.ValidationError({"error": "User is not approved yet."})
        except UserApproval.DoesNotExist:
            raise serializers.ValidationError({"error": "User approval record not found."})
        attrs["username"] = user.username
        data = super().validate(attrs)

        try:
            user_info = UserInformation.objects.get(user=user)
            data["userinfo"] = {
                "role": user_info.role,
                "username": user.username,
                "user_email": user.email,
                "first_name": user.first_name,
                "last_name": user.last_name,
                "approval_status": approval.approval_status,
                 "profile_lock": user_info.profile_lock  
            }
        except UserInformation.DoesNotExist:
            data["userinfo"] = None  

        return data

class UserSerializer(serializers.ModelSerializer):
    full_name = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ['id', 'username', 'full_name', 'email', 'userinformation']
        depth = 1

    def get_full_name(self, obj):
        return obj.userinformation.full_name


class SignupSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ['id', 'username', 'first_name',
                  'last_name', 'email', 'password']
        extra_kwargs = {'email': {'required': True},
                        'password': {'write_only': True}}

    def create(self, validated_data):
        if validate_password(validated_data['password']) == None:
            password = make_password(validated_data['password'])
            user = User.objects.create(
                username=validated_data['username'],
                first_name=validated_data['first_name'],
                last_name=validated_data['last_name'],
                email=validated_data['email'],
                password=password
            )

        return user


class PasswordUpdateSerializer(serializers.Serializer):
    current_password = serializers.CharField(write_only=True, required=True)
    new_password = serializers.CharField(write_only=True, required=True)
    confirm_password = serializers.CharField(write_only=True, required=True)

    def validate_current_password(self, value):
        user = self.context['request'].user
        if not user.check_password(value):
            raise serializers.ValidationError("Current password is incorrect.")
        return value

    def validate(self, attrs):
        new_password = attrs.get('new_password')
        confirm_password = attrs.get('confirm_password')

        if new_password != confirm_password:
            raise serializers.ValidationError({"password": "New password and confirmation do not match."})

        # Validate the new password using Django's built-in validators
        try:
            validate_password(new_password, self.context['request'].user)
        except ValidationError as e:
            raise serializers.ValidationError({"new_password": e.messages})

        return attrs


class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInformation
        fields = ['id', 'phone_number', 'image', 'location', 'dob', 'pin_code', 'time_zone', 'gender']
