"""Serializers for RBAC endpoints."""

from rest_framework import serializers

from .models import Permission, Role, User, UserRole


class PermissionSerializer(serializers.ModelSerializer):
    codename = serializers.CharField(read_only=True)

    class Meta:
        model = Permission
        fields = ["id", "domain", "action", "label", "codename"]
        read_only_fields = fields


class RoleSerializer(serializers.ModelSerializer):
    permissions = PermissionSerializer(many=True, read_only=True)
    permission_ids = serializers.PrimaryKeyRelatedField(
        queryset=Permission.objects.all(),
        many=True, write_only=True, required=False, source="permissions",
    )
    user_count = serializers.SerializerMethodField()

    class Meta:
        model = Role
        fields = [
            "id", "name", "slug", "description", "is_system",
            "permissions", "permission_ids", "user_count",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "is_system", "created_at", "updated_at"]

    def get_user_count(self, obj) -> int:
        anno = getattr(obj, "user_count_anno", None)
        if anno is not None:
            return anno
        return obj.user_assignments.count()


class AdminUserSerializer(serializers.ModelSerializer):
    """User shape for the admin Users page (with roles attached)."""
    full_name = serializers.SerializerMethodField()
    roles = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = [
            "id", "email", "username", "first_name", "last_name", "full_name",
            "avatar", "is_active", "is_staff", "is_superuser",
            "last_login", "date_joined", "roles",
        ]
        read_only_fields = fields

    def get_full_name(self, obj) -> str:
        return obj.get_full_name() or obj.username

    def get_roles(self, obj) -> list:
        # Reads the prefetched user_roles__role (see AdminUserViewSet queryset).
        return [
            {"id": ur.role.id, "slug": ur.role.slug, "name": ur.role.name}
            for ur in obj.user_roles.all()
        ]


class AssignRolesSerializer(serializers.Serializer):
    role_ids = serializers.ListField(
        child=serializers.IntegerField(), allow_empty=True
    )
