from datetime import datetime
from typing import Optional

from async_property import async_property

from core.typing import SerialId
from core.database.abc.db_model_abc import DbModelABC
from data.schemas.permission.permission_dao import permissionDao
from service.permission.permissions_enum import Permissions


class Role(DbModelABC):
    def __init__(
        self,
        id: SerialId,
        name: str,
        description: str,
        deleted: bool = False,
        editor_id: Optional[SerialId] = None,
        created: Optional[datetime] = None,
        updated: Optional[datetime] = None,
    ):
        DbModelABC.__init__(self, id, deleted, editor_id, created, updated)
        self._name = name
        self._description = description

    @property
    def name(self) -> str:
        return self._name

    @name.setter
    def name(self, value: str):
        self._name = value

    @property
    def description(self) -> str:
        return self._description

    @description.setter
    def description(self, value: str):
        self._description = value

    @async_property
    async def permissions(self):
        from data.schemas.permission.role_permission_dao import rolePermissionDao

        return [
            await x.permission for x in await rolePermissionDao.get_by_role_id(self.id)
        ]

    @async_property
    async def users(self):
        from data.schemas.permission.role_user_dao import roleUserDao

        return [await x.user for x in await roleUserDao.get_by_role_id(self.id)]

    async def has_permission(self, permission: Permissions) -> bool:
        from data.schemas.permission.role_permission_dao import rolePermissionDao

        p = await permissionDao.get_by_name(permission.value)
        return p.id in [x.id for x in await rolePermissionDao.get_by_role_id(self.id)]
