from rest_framework import serializers
from django.contrib.auth.models import User
from django.contrib.auth.password_validation import validate_password
from accounts.models import EmailVerification, PasswordReset, UserProfile


class CustomUserCreateSerializer(serializers.ModelSerializer):
    password1 = serializers.CharField(write_only=True, required=True, validators=[validate_password])
    password2 = serializers.CharField(write_only=True, required=True)
    
    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')
        extra_kwargs = {
            'username': {'required': True},
            'email': {'required': True},
        }

    def validate_username(self, value):
        if User.objects.filter(username=value).exists():
            raise serializers.ValidationError("Username already exists.")
        return value

    def validate_email(self, value):
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError("Email already exists.")
        return value

    def validate_password1(self, value):
        if len(value) < 8:
            raise serializers.ValidationError("Password must be at least 8 characters long.")
        return value

    def validate(self, data):
        if data['password1'] != data['password2']:
            raise serializers.ValidationError({"password2": "Passwords do not match."})
        return data

    def create(self, validated_data):
        password = validated_data.pop('password1')
        validated_data.pop('password2')
        user = User.objects.create_user(**validated_data)
        user.is_active = False  # User must verify email before activation
        user.set_password(password)
        user.save()
        
        # Create email verification token
        email_verification = EmailVerification.objects.create(user=user)
        
        # Create user profile
        UserProfile.objects.create(user=user)
        
        return user


class EmailVerificationSerializer(serializers.Serializer):
    token = serializers.CharField(required=True)

    def validate_token(self, value):
        try:
            email_verification = EmailVerification.objects.get(token=value)
        except EmailVerification.DoesNotExist:
            raise serializers.ValidationError("Invalid verification token.")
        
        if not email_verification.is_token_valid():
            raise serializers.ValidationError("Verification token has expired.")
        
        return value


class UserProfileSerializer(serializers.ModelSerializer):
    first_name = serializers.CharField(source='user.first_name', max_length=150, required=False)
    last_name = serializers.CharField(source='user.last_name', max_length=150, required=False)
    
    class Meta:
        model = UserProfile
        fields = ('first_name', 'last_name', 'mobile_number', 'role', 'skills', 'bio', 'experience_years', 'profile_picture', 'cv')
    
    def update(self, instance, validated_data):
        # Handle first_name and last_name updates on the User model
        user_data = validated_data.pop('user', {})
        if 'first_name' in user_data:
            instance.user.first_name = user_data['first_name']
        if 'last_name' in user_data:
            instance.user.last_name = user_data['last_name']
        instance.user.save()
        
        # Update UserProfile fields
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        
        return instance


class CustomUserSerializer(serializers.ModelSerializer):
    is_email_verified = serializers.SerializerMethodField()
    is_admin = serializers.SerializerMethodField()
    profile = UserProfileSerializer(read_only=True)
    
    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'is_email_verified', 'is_admin', 'profile')
    
    def get_is_email_verified(self, obj):
        try:
            return obj.email_verification.is_verified
        except:
            return False
    
    def get_is_admin(self, obj):
        return obj.is_staff and obj.is_superuser


class ForgotPasswordSerializer(serializers.Serializer):
    email = serializers.EmailField(required=True)

    def validate_email(self, value):
        try:
            user = User.objects.get(email=value)
        except User.DoesNotExist:
            raise serializers.ValidationError("User with this email does not exist.")
        return value


class ResetPasswordSerializer(serializers.Serializer):
    token = serializers.CharField(required=True)
    new_password = serializers.CharField(write_only=True, required=True, validators=[validate_password])
    confirm_password = serializers.CharField(write_only=True, required=True)

    def validate_new_password(self, value):
        if len(value) < 8:
            raise serializers.ValidationError("Password must be at least 8 characters long.")
        return value

    def validate(self, data):
        if data['new_password'] != data['confirm_password']:
            raise serializers.ValidationError({"confirm_password": "Passwords do not match."})
        
        try:
            password_reset = PasswordReset.objects.get(token=data['token'])
        except PasswordReset.DoesNotExist:
            raise serializers.ValidationError({"token": "Invalid password reset token."})
        
        if not password_reset.is_token_valid():
            raise serializers.ValidationError({"token": "Password reset token has expired."})
        
        return data
