import uuid
from datetime import datetime
from typing import Optional

from async_property import async_property

from api.auth.keycloak_client import Keycloak
from core.database.abc.db_model_abc import DbModelABC
from core.typing import SerialId
from service.permission.permissions_enum import Permissions


class User(DbModelABC):
    def __init__(
        self,
        id: SerialId,
        keycloak_id: 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._keycloak_id = keycloak_id

    @property
    def keycloak_id(self) -> str:
        return self._keycloak_id

    @property
    def username(self):
        if self._keycloak_id == str(uuid.UUID(int=0)):
            return "ANONYMOUS"

        return Keycloak.admin.get_user(self._keycloak_id).get("username")

    @property
    def email(self):
        if self._keycloak_id == str(uuid.UUID(int=0)):
            return "ANONYMOUS"

        return Keycloak.admin.get_user(self._keycloak_id).get("email")

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

        return [await x.role for x in await roleUserDao.get_by_user_id(self.id)]

    @async_property
    async def permissions(self):
        from data.schemas.administration.user_dao import userDao

        return await userDao.get_permissions(self.id)

    async def has_permission(self, permission: Permissions) -> bool:
        from data.schemas.administration.user_dao import userDao

        return await userDao.has_permission(self.id, permission)

    async def anonymize(self):
        from data.schemas.administration.user_dao import userDao

        self._keycloak_id = str(uuid.UUID(int=0))
        await userDao.update(self)
