from rest_framework import serializers
from .models import Hub, HubPermission, Tags


# Maps Hub fields -> the HubPermission flag that allows changing them
FIELD_PERMISSION_MAP = {
    'name': 'changing_name',
    'description': 'changing_description',
    'icon': 'changing_icon',
    'banner': 'changing_banner',
    'members': 'managing_members',
}


class TransferInitSerializer(serializers.Serializer):
    user_id = serializers.IntegerField(help_text="PK of the user to transfer ownership to.")


class TransferVerifySerializer(serializers.Serializer):
    token = serializers.UUIDField(help_text="Transfer token sent to the new owner.")


class TagsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tags
        fields = ['id', 'name', 'description', 'color']


class HubPermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = HubPermission
        fields = [
            'id', 'user',
            'changing_name', 'changing_description', 'changing_icon', 'changing_banner',
            'managing_members', 'managing_posts', 'managing_chats',
        ]


class HubSerializer(serializers.ModelSerializer):
    tags = TagsSerializer(many=True, read_only=True)
    moderators = HubPermissionSerializer(many=True, read_only=True)

    class Meta:
        model = Hub
        fields = [
            'id', 'name', 'description', 'owner',
            'icon', 'banner', 'members', 'is_public',
            'tags', 'moderators',
        ]
        read_only_fields = ['owner']

    def validate(self, attrs):
        hub = self.instance  # None on create — no restrictions needed
        if hub is None:
            return attrs

        request = self.context.get('request')
        if request is None:
            return attrs

        user = request.user

        # Owner and superuser bypass field-level checks
        if hub.owner == user or user.is_superuser:
            return attrs

        # Moderator: enforce per-field permission flags
        try:
            perm = hub.moderators.get(user=user)
            
        except HubPermission.DoesNotExist:
            raise serializers.ValidationError('You do not have permission to edit this hub.')

        for field in attrs:
            flag = FIELD_PERMISSION_MAP.get(field)
            if flag and not getattr(perm, flag, False):
                raise serializers.ValidationError(
                    {field: 'You do not have permission to change this field.'}
                )

        return attrs
