"""
Permission Serializers — DRF serializers for role/permission management.
"""
from rest_framework import serializers

from .models import (
    Permission, PermissionAction, Role, RolePermission,
    UserRole, FieldPermission, UserPermission,
    ObjectRelation, RelationType, RAICPolicy,
)


# ─── Permission ─────────────────────────────────────────────


class PermissionSerializer(serializers.ModelSerializer):
    """Permission read serializer."""
    class Meta:
        model = Permission
        fields = [
            'id', 'codename', 'name', 'description',
            'module', 'resource', 'action', 'custom_action',
            'is_sensitive', 'created_at',
        ]
        read_only_fields = fields


class PermissionGroupedSerializer(serializers.Serializer):
    """Grouped permissions by module → resource."""
    module = serializers.CharField()
    resources = serializers.ListField()


# ─── Role ────────────────────────────────────────────────────


class RolePermissionInlineSerializer(serializers.ModelSerializer):
    """Inline serializer for role permissions."""
    permission_codename = serializers.CharField(source='permission.codename', read_only=True)
    permission_name = serializers.CharField(source='permission.name', read_only=True)
    
    class Meta:
        model = RolePermission
        fields = ['id', 'permission', 'permission_codename', 'permission_name', 'constraints', 'priority']


class RoleListSerializer(serializers.ModelSerializer):
    """Role list serializer (lightweight)."""
    users_count = serializers.SerializerMethodField()
    
    class Meta:
        model = Role
        fields = [
            'id', 'name', 'slug', 'description', 'is_system',
            'is_active', 'module', 'parent', 'users_count',
            'created_at', 'updated_at',
        ]
        read_only_fields = ['created_at', 'updated_at']
    
    def get_users_count(self, obj):
        return obj.role_users.count()


class RoleDetailSerializer(serializers.ModelSerializer):
    """Role detail serializer with permissions."""
    permissions = RolePermissionInlineSerializer(source='role_permissions', many=True, read_only=True)
    users_count = serializers.SerializerMethodField()
    parent_name = serializers.CharField(source='parent.name', read_only=True, default=None)
    
    class Meta:
        model = Role
        fields = [
            'id', 'name', 'slug', 'description', 'is_system',
            'is_active', 'module', 'parent', 'parent_name',
            'metadata', 'permissions', 'users_count',
            'created_at', 'updated_at',
        ]
        read_only_fields = ['created_at', 'updated_at']
    
    def get_users_count(self, obj):
        return obj.role_users.count()


class RoleCreateUpdateSerializer(serializers.ModelSerializer):
    """Role create/update serializer."""
    class Meta:
        model = Role
        fields = [
            'id', 'name', 'slug', 'description', 'is_system',
            'is_active', 'module', 'parent', 'metadata',
        ]
        read_only_fields = ['id']
    
    def validate_slug(self, value):
        tenant = getattr(self.context.get('request'), 'tenant', None)
        qs = Role.objects.filter(slug=value)
        if tenant:
            qs = qs.filter(tenant=tenant)
        if self.instance:
            qs = qs.exclude(pk=self.instance.pk)
        if qs.exists():
            raise serializers.ValidationError("Role with this slug already exists.")
        return value


# ─── UserRole ────────────────────────────────────────────────


class UserRoleSerializer(serializers.ModelSerializer):
    """UserRole serializer."""
    user_email = serializers.CharField(source='user.email', read_only=True)
    user_full_name = serializers.CharField(source='user.full_name', read_only=True)
    role_name = serializers.CharField(source='role.name', read_only=True)
    role_slug = serializers.CharField(source='role.slug', read_only=True)
    org_unit_name = serializers.CharField(
        source='organizational_unit.name', read_only=True, default=None
    )
    
    class Meta:
        model = UserRole
        fields = [
            'id', 'user', 'user_email', 'user_full_name',
            'role', 'role_name', 'role_slug',
            'organizational_unit', 'org_unit_name',
            'include_descendant_units', 'scope',
            'starts_at', 'expires_at',
            'assigned_by', 'assignment_reason',
            'created_at',
        ]
        read_only_fields = ['id', 'created_at']


# ─── UserPermission ──────────────────────────────────────────


class UserPermissionSerializer(serializers.ModelSerializer):
    """UserPermission override serializer."""
    user_email = serializers.CharField(source='user.email', read_only=True)
    permission_codename = serializers.CharField(source='permission.codename', read_only=True)
    permission_name = serializers.CharField(source='permission.name', read_only=True)
    granted_by_email = serializers.CharField(
        source='granted_by.email', read_only=True, default=None
    )
    
    class Meta:
        model = UserPermission
        fields = [
            'id', 'user', 'user_email',
            'permission', 'permission_codename', 'permission_name',
            'allow', 'reason',
            'granted_by', 'granted_by_email',
            'starts_at', 'expires_at',
            'created_at', 'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']
    
    def create(self, validated_data):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            validated_data['granted_by'] = request.user
        return super().create(validated_data)


# ─── ObjectRelation ──────────────────────────────────────────


class ObjectRelationSerializer(serializers.ModelSerializer):
    """ObjectRelation serializer for RAIC."""
    user_email = serializers.CharField(source='user.email', read_only=True)
    user_full_name = serializers.CharField(source='user.full_name', read_only=True)
    
    class Meta:
        model = ObjectRelation
        fields = [
            'id', 'object_type', 'object_id',
            'user', 'user_email', 'user_full_name',
            'relation_type', 'custom_relation',
            'module', 'metadata', 'created_at',
        ]
        read_only_fields = ['id', 'created_at']


# ─── RAICPolicy ──────────────────────────────────────────────


class RAICPolicySerializer(serializers.ModelSerializer):
    """RAICPolicy serializer."""
    permission_codename = serializers.CharField(source='permission.codename', read_only=True)
    permission_name = serializers.CharField(source='permission.name', read_only=True)
    
    class Meta:
        model = RAICPolicy
        fields = [
            'id', 'module', 'object_type', 'relation_type',
            'permission', 'permission_codename', 'permission_name',
            'is_active', 'created_at',
        ]
        read_only_fields = ['id', 'created_at']


# ─── Assign Permission to Role ───────────────────────────────


class RolePermissionAssignSerializer(serializers.Serializer):
    """Assign/remove permissions to/from a role."""
    permission_ids = serializers.ListField(
        child=serializers.IntegerField(),
        help_text="List of permission IDs to assign"
    )
    constraints = serializers.JSONField(required=False, default=dict)


# ─── My Permissions Response ─────────────────────────────────


class MyPermissionsSerializer(serializers.Serializer):
    """Response for /me/permissions endpoint."""
    permissions = serializers.ListField(child=serializers.CharField())
    roles = serializers.ListField(child=serializers.DictField())
    is_superuser = serializers.BooleanField()
