from gvsds.apps.core.models import User
from gvsdsdk.models import UserRole, Role, RolePermission, Permission, UserABAC
from rest_framework.permissions import BasePermission


class IsAdminUser(BasePermission):
    """仅允许管理员（IsStaff 或 IsSuperuser）访问"""

    def has_permission(self, request, view):
        user = request.user
        if not user or not user.is_authenticated:
            return False
        if not isinstance(user, User):
            return False
        return user.IsStaff or user.IsSuperuser


class IsCompanyMember(BasePermission):
    """验证用户当前角色属于目标数据所在公司"""
    def has_object_permission(self, request, view, obj):
        if not request.current_company_uuid:
            return False
        obj_company = getattr(obj, 'CompanyUUID_id', None) or getattr(obj, 'CompanyUUID', None)
        if obj_company is None:
            return True  # 无公司归属的数据不做限制
        return str(obj_company) == str(request.current_company_uuid)


class CompanyScopedMixin:
    """ViewSet Mixin：自动按当前角色所属公司过滤 queryset"""
    company_field = 'CompanyUUID'  # 可在 ViewSet 中覆盖

    def get_queryset(self):
        qs = super().get_queryset()
        company_uuid = getattr(self.request, 'current_company_uuid', None)
        if company_uuid and hasattr(qs.model, self.company_field):
            qs = qs.filter(**{self.company_field: company_uuid})
        return qs

    def perform_create(self, serializer):
        company_uuid = getattr(self.request, 'current_company_uuid', None)
        if company_uuid and hasattr(serializer.Meta.model, 'CompanyUUID'):
            serializer.save(CompanyUUID=company_uuid)
        else:
            serializer.save()


def PermissionVerifier(permission, attributes, user=None, request=None):
    """权限验证器——混合 ABAC + RBAC 检查

    RBAC 仅检查当前角色（CurrentRoleUUID Cookie 指定的角色）的权限，
    通过 RolePermission → Permission 链路查询，按当前公司过滤。
    超级管理员/员工直接放行。
    """
    if not permission:
        return True
    if user is None:
        return False
    if not isinstance(user, User):
        return False

    # 超级管理员和员工直接放行
    if user.IsSuperuser or user.IsStaff:
        return True

    current_role = getattr(request, 'current_role', None) if request else None
    current_company = getattr(request, 'current_company_uuid', None) if request else None

    for attr in attributes:
        # ABAC 检查
        abac_match = UserABAC.objects.filter(
            UserUUID=user.UserUUID,
            HierarchicalPermissionIdentifiers=attr
        ).first()
        if abac_match:
            continue

        # RBAC 检查：仅检查当前角色，按公司过滤权限
        if current_role and isinstance(current_role, Role):
            if current_role.RoleStatus != 1:
                return False
            rp_qs = RolePermission.objects.filter(
                RoleUUID=current_role.RoleUUID
            )
            if current_company:
                rp_qs = rp_qs.filter(CompanyUUID=current_company)
            perm_uuids = rp_qs.values_list('PermUUID', flat=True)
            rbac_result = Permission.objects.filter(
                PermUUID__in=perm_uuids,
                PermCode=attr,
                PermStatus=1,
            ).exists()
        else:
            # 无 current_role 时回退到用户所有活跃角色
            user_role_uuids = UserRole.objects.filter(
                UserUUID=user.UserUUID
            ).values_list('RoleUUID', flat=True)
            active_role_uuids = Role.objects.filter(
                RoleUUID__in=user_role_uuids,
                RoleStatus=1,
            ).values_list('RoleUUID', flat=True)
            rp_qs = RolePermission.objects.filter(
                RoleUUID__in=active_role_uuids
            )
            if current_company:
                rp_qs = rp_qs.filter(CompanyUUID=current_company)
            perm_uuids = rp_qs.values_list('PermUUID', flat=True)
            rbac_result = Permission.objects.filter(
                PermUUID__in=perm_uuids,
                PermCode=attr,
                PermStatus=1,
            ).exists()

        if rbac_result:
            continue
        return False
    return True
