from api_graphql.service.collection_result import CollectionResult
from api_graphql.service.query_context import QueryContext
from data.schemas.public.group_dao import groupDao
from data.schemas.public.user_space_dao import userSpaceDao
from data.schemas.public.user_space_user_dao import userSpaceUserDao
from service.permission.permissions_enum import Permissions


async def by_user_space_assignment_resolver(ctx: QueryContext) -> bool:
    if not isinstance(ctx.data, CollectionResult):
        return False

    if len(ctx.data.nodes) == 0:
        return True

    user = ctx.user

    assigned_user_space_ids = {
        us.user_space_id for us in await userSpaceUserDao.get_by_user_id(user.id)
    }

    for node in ctx.data.nodes:
        user_space = await node.user_space
        if user_space is None:
            continue

        if user_space.owner_id == user.id or user_space.id in assigned_user_space_ids:
            return True

    return len(ctx.data.nodes) == 0


async def by_group_assignment_resolver(ctx: QueryContext) -> bool:
    if not isinstance(ctx.data, CollectionResult):
        return False

    if ctx.has_permission(Permissions.short_urls_by_assignment):
        groups = [await x.group for x in ctx.data.nodes]
        role_ids = {x.id for x in await ctx.user.roles}
        filtered_groups = [
            g.id
            for g in groups
            if g is not None
            and (roles := await groupDao.get_roles(g.id))
            and all(r.id in role_ids for r in roles)
        ]

        return all(
            (await node.group) is not None and (await node.group).id in filtered_groups
            for node in ctx.data.nodes
        )

    return False


async def has_assigned_user_spaces(ctx: QueryContext):
    user_spaces = await userSpaceDao.get_assigned_by_user_id(ctx.user.id)
    return len(user_spaces) > 0
