"""
Helper functions para checagem e listagem de permissões
Funções principais para o sistema de permissões multi-sistema
"""


def user_has_permission(user_id, organization_id, permission_codename, system_id):
    """
    Verifica se um usuário tem uma permissão específica.
    
    Fluxo:
    1. Busca Member (user + organization)
    2. Busca MemberSystemGroup (member + system)
    3. Busca GroupOrganizationPermissions
    4. Verifica se permission_codename está no grupo
    
    Args:
        user_id: ID do usuário
        organization_id: ID da organização
        permission_codename: Código da permissão (ex: 'create_invoices')
        system_id: ID do sistema
    
    Returns:
        bool: True se usuário tem a permissão, False caso contrário
    
    Usage:
        from shared_auth.permissions_helpers import user_has_permission
        
        if user_has_permission(5, 1, 'create_invoices', 2):
            # Usuário pode criar faturas
            pass
    """
    from .utils import (
        get_group_organization_permissions_model,
        get_member_model,
        get_member_system_group_model,
    )
    
    # 1. Buscar membro
    Member = get_member_model()
    member = Member.objects.filter(
        user_id=user_id,
        organization_id=organization_id
    ).first()
    
    if not member:
        return False
    
    # 2. Buscar grupo do membro no sistema
    MemberSystemGroup = get_member_system_group_model()
    member_group = MemberSystemGroup.objects.get_group_for_member_and_system(
        member.id,
        system_id
    )
    
    if not member_group:
        return False
    
    # 3. Buscar grupo de permissões
    GroupOrgPermissions = get_group_organization_permissions_model()
    try:
        group = GroupOrgPermissions.objects.get(pk=member_group.group_id)
    except GroupOrgPermissions.DoesNotExist:
        return False
    
    return group.permissions.filter(
        codename=permission_codename,
        system_id=system_id
    ).exists()


def get_user_permissions(user_id, organization_id, system_id):
    """
    Retorna todas as permissões do usuário em um sistema.
    
    Args:
        user_id: ID do usuário
        organization_id: ID da organização
        system_id: ID do sistema
    
    Returns:
        QuerySet[Permission]: Permissões do usuário
    
    Usage:
        from shared_auth.permissions_helpers import get_user_permissions
        
        perms = get_user_permissions(5, 1, 2)
        for perm in perms:
            print(perm.codename)
    """
    from .utils import (
        get_group_organization_permissions_model,
        get_member_model,
        get_member_system_group_model,
        get_permission_model,
    )
    
    Permission = get_permission_model()
    
    # 1. Buscar membro
    Member = get_member_model()
    member = Member.objects.filter(
        user_id=user_id,
        organization_id=organization_id
    ).first()
    
    if not member:
        return Permission.objects.none()
    
    # 2. Buscar grupo do membro no sistema
    MemberSystemGroup = get_member_system_group_model()
    member_group = MemberSystemGroup.objects.get_group_for_member_and_system(
        member.id,
        system_id
    )
    
    if not member_group:
        return Permission.objects.none()
    
    # 3. Buscar grupo de permissões
    GroupOrgPermissions = get_group_organization_permissions_model()
    try:
        group = GroupOrgPermissions.objects.get(pk=member_group.group_id)
    except GroupOrgPermissions.DoesNotExist:
        return Permission.objects.none()
    
    # 4. Retornar permissões do grupo
    return group.permissions.all()


def get_user_permission_codenames(user_id, organization_id, system_id):
    """
    Retorna lista de codenames de permissões do usuário.
    
    Args:
        user_id: ID do usuário
        organization_id: ID da organização
        system_id: ID do sistema
    
    Returns:
        List[str]: Lista de codenames
    
    Usage:
        from shared_auth.permissions_helpers import get_user_permission_codenames
        
        codenames = get_user_permission_codenames(5, 1, 2)
        # ['create_invoices', 'edit_invoices', 'view_reports']
    """
    permissions = get_user_permissions(user_id, organization_id, system_id)
    return list(permissions.values_list('codename', flat=True))


def get_organization_permissions(organization_id, system_id):
    """
    Retorna permissões disponíveis no plano da organização.
    
    Fluxo:
    1. Busca Subscription ativa
    2. Busca Plan
    3. Retorna permissões dos GroupPermissions do plano
    
    Args:
        organization_id: ID da organização
        system_id: ID do sistema
    
    Returns:
        QuerySet[Permission]: Permissões do plano
    
    Usage:
        from shared_auth.permissions_helpers import get_organization_permissions
        
        perms = get_organization_permissions(1, 2)
        for perm in perms:
            print(perm.codename)
    """
    from .utils import get_permission_model, get_subscription_model
    
    Permission = get_permission_model()
    
    # 1. Buscar assinatura ativa
    Subscription = get_subscription_model()
    subscription = Subscription.objects.valid_for_organization_and_system(
        organization_id,
        system_id
    )
    
    if not subscription:
        return Permission.objects.none()
    
    # 2. Buscar plano
    plan = subscription.plan
    if not plan:
        return Permission.objects.none()
    
    # 3. Buscar grupos de permissões do plano
    group_permissions = plan.group_permissions.all()
    
    # 4. Coletar todas as permissões dos grupos
    permission_ids = []
    for group in group_permissions:
        permission_ids.extend(
            group.permissions.values_list('id', flat=True)
        )
    
    # 5. Retornar permissões únicas
    return Permission.objects.filter(id__in=set(permission_ids))


def get_organization_permission_codenames(organization_id, system_id):
    """
    Retorna lista de codenames de permissões do plano da organização.
    
    Args:
        organization_id: ID da organização
        system_id: ID do sistema
    
    Returns:
        List[str]: Lista de codenames
    
    Usage:
        from shared_auth.permissions_helpers import get_organization_permission_codenames
        
        codenames = get_organization_permission_codenames(1, 2)
    """
    permissions = get_organization_permissions(organization_id, system_id)
    return list(permissions.values_list('codename', flat=True))


def user_has_any_permission(user_id, organization_id, permission_codenames, system_id):
    """
    Verifica se usuário tem pelo menos uma das permissões.
    
    Args:
        user_id: ID do usuário
        organization_id: ID da organização
        permission_codenames: Lista de codenames
        system_id: ID do sistema
    
    Returns:
        bool: True se tem pelo menos uma permissão
    
    Usage:
        from shared_auth.permissions_helpers import user_has_any_permission
        
        if user_has_any_permission(5, 1, ['view_reports', 'create_reports'], 2):
            # Usuário pode ver ou criar relatórios
            pass
    """
    for codename in permission_codenames:
        if user_has_permission(user_id, organization_id, codename, system_id):
            return True
    return False


def user_has_all_permissions(user_id, organization_id, permission_codenames, system_id):
    """
    Verifica se usuário tem todas as permissões.
    
    Args:
        user_id: ID do usuário
        organization_id: ID da organização
        permission_codenames: Lista de codenames
        system_id: ID do sistema
    
    Returns:
        bool: True se tem todas as permissões
    
    Usage:
        from shared_auth.permissions_helpers import user_has_all_permissions
        
        if user_has_all_permissions(5, 1, ['create_invoices', 'edit_invoices'], 2):
            # Usuário pode criar E editar faturas
            pass
    """
    for codename in permission_codenames:
        if not user_has_permission(user_id, organization_id, codename, system_id):
            return False
    return True
