# stdlib
from typing import Optional
from typing import Union
from datetime import datetime

# third party
from nacl.encoding import HexEncoder
from nacl.signing import SigningKey
from pydantic import BaseModel
from pydantic import EmailStr


class BaseUser(BaseModel):
    email: Optional[EmailStr]
    name: Optional[str]
    role: Union[Optional[int], Optional[str]]  # TODO: Should be int in SyftUser
    daa_pdf: Optional[bytes] = b""

    class Config:
        orm_mode = True


class UserCreate(BaseUser):
    email: EmailStr
    role: str = "Data Scientist"
    name: str
    password: str
    institution: Optional[str]
    website: Optional[str]


class ApplicantStatus(BaseModel):
    status: str


class UserUpdate(BaseUser):
    password: Optional[str]
    budget: Optional[float]


class UserCandidate(BaseUser):
    email: EmailStr
    status: str = "pending"
    name: str


class User(BaseUser):
    id: int
    role: Union[int, str]  # TODO: This should be int. Perhaps add role_name instead?
    budget_spent: Optional[float]
    allocated_budget: Optional[float]
    institution: Optional[str]
    website: Optional[str]
    added_by: Optional[str]
    created_at: Optional[str]


class UserPrivate(User):
    private_key: str
    created_at: Optional[datetime]


    def get_signing_key(self) -> SigningKey:
        return SigningKey(self.private_key.encode(), encoder=HexEncoder)


class UserSyft(User):
    hashed_password: str
    salt: str
    verify_key: str

@@ -2,16 +2,46 @@
  stdlib%0A
+from datetime import datetime%0A
 from typ
@@ -88,38 +88,8 @@
 nion
-%0Afrom datetime import datetime
 %0A%0A# 
@@ -1170,32 +1170,38 @@
     created_at: 
+Union%5B
 Optional%5Bstr%5D%0A%0A%0A
@@ -1189,32 +1189,53 @@
 on%5BOptional%5Bstr%5D
+, Optional%5Bdatetime%5D%5D
 %0A%0A%0Aclass UserPri
@@ -1271,44 +1271,8 @@
 str%0A
-    created_at: Optional%5Bdatetime%5D%0A%0A
 %0A   

Fix users model