from rest_framework import serializers

from .models import Module, Feature, Permission, Role, StaffRole


class PermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Permission
        fields = ('id', 'codename', 'action', 'name')


class FeatureSerializer(serializers.ModelSerializer):
    permissions = PermissionSerializer(many=True, read_only=True)

    class Meta:
        model = Feature
        fields = ('id', 'code', 'name', 'description', 'permissions')


class ModuleSerializer(serializers.ModelSerializer):
    features = FeatureSerializer(many=True, read_only=True)

    class Meta:
        model = Module
        fields = ('id', 'code', 'name', 'description', 'casl_subject', 'icon', 'features')


class RoleListSerializer(serializers.ModelSerializer):
    permission_count = serializers.SerializerMethodField()
    staff_count = serializers.SerializerMethodField()

    class Meta:
        model = Role
        fields = ('id', 'name', 'description', 'is_system',
                  'permission_count', 'staff_count',
                  'created_on', 'last_updated_on')

    def get_permission_count(self, obj):
        return obj.permissions.count()

    def get_staff_count(self, obj):
        return obj.staff_assignments.filter(is_active=True).count()


class RoleDetailSerializer(serializers.ModelSerializer):
    permission_codenames = serializers.SerializerMethodField()

    class Meta:
        model = Role
        fields = ('id', 'name', 'description', 'is_system',
                  'permission_codenames', 'created_on', 'last_updated_on')

    def get_permission_codenames(self, obj):
        return list(obj.permissions.values_list('codename', flat=True))


class StaffRoleAssignmentSerializer(serializers.ModelSerializer):
    role_name = serializers.CharField(source='role.name', read_only=True)
    staff_name = serializers.SerializerMethodField()
    staff_number = serializers.CharField(source='staff_profile.staff_number', read_only=True)

    class Meta:
        model = StaffRole
        fields = ('id', 'staff_profile', 'staff_number', 'staff_name',
                  'role', 'role_name', 'branch', 'main_branch_only',
                  'is_active', 'created_on')

    def get_staff_name(self, obj):
        sp = obj.staff_profile
        return f'{sp.first_name} {sp.last_name}'.strip()
