"""
CODH Users Serializers
"""

from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from django.core.validators import EmailValidator
from .models import (
    User, Permission, Role, UserSession, UserActivity,
    UserPreference, PasswordResetToken, EmailVerificationToken,
    Team, TeamMember
)

User = get_user_model()


class PermissionSerializer(serializers.ModelSerializer):
    """Permission serializer"""
    
    class Meta:
        model = Permission
        fields = ['id', 'name', 'codename', 'description', 'category']


class RoleSerializer(serializers.ModelSerializer):
    """Role serializer with permissions"""
    
    permissions = PermissionSerializer(many=True, read_only=True)
    permission_ids = serializers.ListField(
        child=serializers.UUIDField(),
        write_only=True,
        required=False
    )
    
    class Meta:
        model = Role
        fields = ['id', 'name', 'code', 'description', 'permissions', 'permission_ids', 'level', 'is_active']
    
    def create(self, validated_data):
        permission_ids = validated_data.pop('permission_ids', [])
        role = Role.objects.create(**validated_data)
        
        if permission_ids:
            permissions = Permission.objects.filter(id__in=permission_ids)
            role.permissions.set(permissions)
        
        return role
    
    def update(self, instance, validated_data):
        permission_ids = validated_data.pop('permission_ids', None)
        
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        
        if permission_ids is not None:
            permissions = Permission.objects.filter(id__in=permission_ids)
            instance.permissions.set(permissions)
        
        return instance


class UserListSerializer(serializers.ModelSerializer):
    """User list serializer (minimal data)"""
    
    role_display = serializers.CharField(source='get_role_display', read_only=True)
    
    class Meta:
        model = User
        fields = [
            'id', 'email', 'first_name', 'last_name', 'full_name',
            'role', 'role_display', 'is_active', 'email_verified',
            'company_name', 'avatar', 'date_joined', 'last_login_at'
        ]


class UserDetailSerializer(serializers.ModelSerializer):
    """User detail serializer"""
    
    role_display = serializers.CharField(source='get_role_display', read_only=True)
    permissions = serializers.SerializerMethodField()
    preferences = serializers.SerializerMethodField()
    
    class Meta:
        model = User
        fields = [
            'id', 'email', 'first_name', 'last_name', 'full_name',
            'phone', 'company_name', 'company_website', 'company_address',
            'role', 'role_display', 'is_active', 'is_staff',
            'email_verified', 'phone_verified', 'identity_verified',
            'two_factor_enabled', 'timezone', 'language', 'currency',
            'avatar', 'wordpress_user_id', 'wordpress_site_url',
            'date_joined', 'last_login_at', 'last_activity_at',
            'permissions', 'preferences'
        ]
        read_only_fields = [
            'id', 'email_verified', 'phone_verified', 'identity_verified',
            'date_joined', 'last_login_at', 'last_activity_at'
        ]
    
    def get_permissions(self, obj):
        """Get user permissions"""
        return [p.codename for p in obj.get_permissions()]
    
    def get_preferences(self, obj):
        """Get user preferences"""
        try:
            pref = obj.preferences
            return {
                'email_notifications': pref.email_notifications,
                'push_notifications': pref.push_notifications,
                'sms_notifications': pref.sms_notifications,
                'notify_project_updates': pref.notify_project_updates,
                'notify_billing': pref.notify_billing,
                'notify_hosting': pref.notify_hosting,
                'notify_marketing': pref.notify_marketing,
            }
        except:
            return None


class UserCreateSerializer(serializers.ModelSerializer):
    """User creation serializer"""
    
    password = serializers.CharField(write_only=True, validators=[validate_password])
    password_confirm = serializers.CharField(write_only=True)
    
    class Meta:
        model = User
        fields = [
            'email', 'password', 'password_confirm',
            'first_name', 'last_name', 'phone',
            'company_name', 'role'
        ]
    
    def validate(self, data):
        if data['password'] != data.pop('password_confirm'):
            raise serializers.ValidationError("Passwords do not match")
        return data
    
    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        
        # Create preferences
        UserPreference.objects.create(user=user)
        
        return user


class UserUpdateSerializer(serializers.ModelSerializer):
    """User update serializer"""
    
    class Meta:
        model = User
        fields = [
            'first_name', 'last_name', 'phone',
            'company_name', 'company_website', 'company_address',
            'timezone', 'language', 'currency', 'avatar'
        ]


class PasswordChangeSerializer(serializers.Serializer):
    """Password change serializer"""
    
    current_password = serializers.CharField(write_only=True)
    new_password = serializers.CharField(write_only=True, validators=[validate_password])
    new_password_confirm = serializers.CharField(write_only=True)
    
    def validate(self, data):
        if data['new_password'] != data['new_password_confirm']:
            raise serializers.ValidationError("New passwords do not match")
        return data
    
    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


class PasswordResetRequestSerializer(serializers.Serializer):
    """Password reset request serializer"""
    
    email = serializers.EmailField()


class PasswordResetConfirmSerializer(serializers.Serializer):
    """Password reset confirmation serializer"""
    
    token = serializers.CharField()
    new_password = serializers.CharField(validators=[validate_password])
    new_password_confirm = serializers.CharField()
    
    def validate(self, data):
        if data['new_password'] != data['new_password_confirm']:
            raise serializers.ValidationError("Passwords do not match")
        return data


class UserSessionSerializer(serializers.ModelSerializer):
    """User session serializer"""
    
    is_current = serializers.SerializerMethodField()
    
    class Meta:
        model = UserSession
        fields = [
            'id', 'ip_address', 'country', 'city',
            'user_agent', 'is_active', 'is_current',
            'started_at', 'last_activity_at'
        ]
    
    def get_is_current(self, obj):
        request = self.context.get('request')
        if request:
            return obj.session_key == request.session.session_key
        return False


class UserActivitySerializer(serializers.ModelSerializer):
    """User activity serializer"""
    
    activity_type_display = serializers.CharField(source='get_activity_type_display', read_only=True)
    
    class Meta:
        model = UserActivity
        fields = [
            'id', 'activity_type', 'activity_type_display',
            'description', 'object_type', 'object_id',
            'ip_address', 'created_at'
        ]


class UserPreferenceSerializer(serializers.ModelSerializer):
    """User preference serializer"""
    
    class Meta:
        model = UserPreference
        fields = [
            'email_notifications', 'push_notifications', 'sms_notifications',
            'notify_project_updates', 'notify_billing', 'notify_hosting',
            'notify_marketing', 'dashboard_layout', 'default_view',
            'profile_visible', 'show_activity_status'
        ]


class TeamMemberSerializer(serializers.ModelSerializer):
    """Team member serializer"""
    
    user = UserListSerializer(read_only=True)
    role_display = serializers.CharField(source='get_role_display', read_only=True)
    
    class Meta:
        model = TeamMember
        fields = ['id', 'user', 'role', 'role_display', 'joined_at']


class TeamSerializer(serializers.ModelSerializer):
    """Team serializer"""
    
    owner = UserListSerializer(read_only=True)
    members = TeamMemberSerializer(source='teammember_set', many=True, read_only=True)
    member_count = serializers.IntegerField(source='members.count', read_only=True)
    
    class Meta:
        model = Team
        fields = [
            'id', 'name', 'description', 'owner',
            'members', 'member_count', 'is_active',
            'created_at', 'updated_at'
        ]


class TeamCreateSerializer(serializers.ModelSerializer):
    """Team creation serializer"""
    
    class Meta:
        model = Team
        fields = ['name', 'description']


class AddTeamMemberSerializer(serializers.Serializer):
    """Add member to team serializer"""
    
    email = serializers.EmailField()
    role = serializers.ChoiceField(choices=['admin', 'member', 'viewer'])


class LoginSerializer(serializers.Serializer):
    """Login serializer"""
    
    email = serializers.EmailField()
    password = serializers.CharField(write_only=True)


class RegisterSerializer(serializers.ModelSerializer):
    """Registration serializer"""
    
    password = serializers.CharField(write_only=True, validators=[validate_password])
    password_confirm = serializers.CharField(write_only=True)
    
    class Meta:
        model = User
        fields = [
            'email', 'password', 'password_confirm',
            'first_name', 'last_name', 'company_name'
        ]
    
    def validate(self, data):
        if data['password'] != data.pop('password_confirm'):
            raise serializers.ValidationError("Passwords do not match")
        return data
