from api_graphql.abc.mutation_abc import MutationABC
from api_graphql.input.role_create_input import RoleCreateInput
from api_graphql.input.role_update_input import RoleUpdateInput
from core.logger import APILogger
from data.schemas.permission.permission_dao import permissionDao
from data.schemas.permission.role import Role
from data.schemas.permission.role_dao import roleDao
from data.schemas.permission.role_permission import RolePermission
from data.schemas.permission.role_permission_dao import rolePermissionDao
from service.permission.permissions_enum import Permissions

logger = APILogger(__name__)


class RoleMutation(MutationABC):
    def __init__(self):
        MutationABC.__init__(self, "Role")
        self.mutation(
            "create",
            self.resolve_create,
            RoleCreateInput,
            require_any_permission=[Permissions.roles_create],
        )
        self.mutation(
            "update",
            self.resolve_update,
            RoleUpdateInput,
            require_any_permission=[Permissions.roles_update],
        )
        self.mutation(
            "delete",
            self.resolve_delete,
            require_any_permission=[Permissions.roles_delete],
        )
        self.mutation(
            "restore",
            self.resolve_restore,
            require_any_permission=[Permissions.roles_delete],
        )

    @staticmethod
    async def resolve_create(obj: RoleCreateInput, *_):
        logger.debug(f"create role: {obj.__dict__}")

        role = Role(
            0,
            obj.name,
            obj.description,
        )
        await roleDao.create(role)
        role = await roleDao.get_by_name(role.name)
        await rolePermissionDao.create_many(
            [RolePermission(0, role.id, x) for x in obj.permissions]
        )

        return role

    async def resolve_update(self, obj: RoleUpdateInput, *_):
        logger.debug(f"update role: {obj.__dict__}")
        role = await roleDao.get_by_id(obj.id)
        role.name = obj.get("name", role.name)
        role.description = obj.get("description", role.description)
        await roleDao.update(role)

        await self._resolve_assignments(
            obj.get("permissions", []),
            role,
            RolePermission.role_id,
            RolePermission.permission_id,
            roleDao,
            rolePermissionDao,
            RolePermission,
            permissionDao,
        )

        return role

    @staticmethod
    async def resolve_delete(*_, id: int):
        logger.debug(f"delete role: {id}")
        role = await roleDao.get_by_id(id)
        await roleDao.delete(role)
        return True

    @staticmethod
    async def resolve_restore(*_, id: int):
        logger.debug(f"restore role: {id}")
        role = await roleDao.get_by_id(id)
        await roleDao.restore(role)
        return True
