"""
Pydantic schemas for TOAR database

"""

from typing import List, Dict, Any

from pydantic import BaseModel, validator, Field
from .models import OK_enum

class OrganisationBase(BaseModel):
    id: int = Field(None, description="for internal use only")
    name: str = Field(..., description="Short name (abbreviation) of organisation")
    longname: str = Field(..., description="Long name of organisation")
    kind: str = Field(..., description="Kind of organisation")
    city: str = Field(..., description="City where organisation resides")
    postcode: str = Field(..., description="Postcode of organisation city")
    street_address: str = Field(..., description="Street address of organisation city")
    country: str = Field(..., description="Country to which organisation belongs")
    homepage: str = Field(..., description="Homepage of organisation")

    @validator('kind')
    def check_kind(cls, v):
        return tuple(filter(lambda x: x.value == int(v), OK_enum))[0].string


class OrganisationCreate(OrganisationBase):
    kind: str
    pass

    @validator('kind') 
    def check_kind(cls, v):
        if tuple(filter(lambda x: x.string == v, OK_enum)):
            return v
        else:
            raise ValueError(f"kind of organisation not known: {v}")


class Organisation(OrganisationBase):
    id: int = Field(..., description="for internal use only")

    class Config:
        orm_mode = True


class PersonBase(BaseModel):
    id: int = Field(None, description="for internal use only")
    name: str = Field(..., description="Name of person")
    email: str = Field(..., description="Email address of person")
    phone: str = Field(..., description="Phone number of person")
    isprivate: bool = Field(..., description="Set this flag to true if the contact details shall not be exposed publicly")

    def __str__(self):
        return f"{self.name} <{self.email}>"

    class Meta:
        db_table = 'persons'
#       app_label = 'Person'

class PersonCreate(PersonBase):
    pass


class Person(PersonBase):
    id: int = Field(..., description="for internal use only")

    class Config:
        orm_mode = True

# ======== for nested view =========

class ContactBase(BaseModel):
    id: int = Field(None, description="for internal use only")
    person: Person = Field(..., description="A contact is either a person or an organisation")
    organisation: Organisation = Field(..., description="A contact is either a person or an organisation")

    class Config:
        orm_mode = True

class Contact(ContactBase):
    id: int = Field(..., description="for internal use only")

    class Config:
        orm_mode = True