from datetime import date, datetime
from typing import List, Literal, Optional

from pydantic import Field, BaseModel, validator
from beanie import Indexed

from ..core.models import CrudDocument


class EntityType(BaseModel):
    @property
    def label(self) -> str:
        return self.title


class Individual(EntityType):
    type: Literal['individual'] = 'individual'
    firstname: Indexed(str) = Field(title='Prénom')
    middlename: Indexed(str) = Field(default="", title='Autres prénoms')
    lastname: Indexed(str) = Field(title='Nom de famille')
    surnames: List[Indexed(str)] = Field(
        default=[],
        props={"items-per-row": "4", "numbered": True},
        title="Surnoms"
    )
    day_of_birth: date = Field(default=None, title='Date de naissance')
    place_of_birth: str = Field(default="", title='Lieu de naissance')

    @property
    def label(self) -> str:
        # if len(self.surnames) > 0:
        #     return '{} "{}" {}'.format(self.firstname, self.surnames[0], self.lastname)

        return '{} {}'.format(self.firstname, self.lastname)

    class Config:
        title = 'Particulier'


class Employee(BaseModel):
    role: Indexed(str) = Field(title='Poste')
    entity_id: str = Field(foreignKey={
                                "reference": {
                                    "resource": "entity",
                                    "schema": "Entity",
                                    "condition": "entity_data.type=individual"
                                }
                            },
                            title='Employé'
    )

    class Config:
        title = 'Fiche Employé'


class Corporation(EntityType):
    type: Literal['corporation'] = 'corporation'
    title: Indexed(str) = Field(title='Dénomination sociale')
    activity: Indexed(str) = Field(title='Activité')
    employees: List[Employee] = Field(default=[], title='Employés')

    class Config:
        title = 'Entreprise'


class Institution(Corporation):
    type: Literal['institution'] = 'institution'

    class Config:
        title = 'Institution'


class Entity(CrudDocument):
    """
    Fiche d'un client
    """
    entity_data: Individual | Corporation | Institution = Field(..., discriminator='type')
    label: str = None
    address: str = Field(default="", title='Adresse')

    @validator("label", always=True)
    def generate_label(cls, v, values, **kwargs):
        if 'entity_data' not in values:
            return v
        return values['entity_data'].label

    class Settings(CrudDocument.Settings):
        fulltext_search = ['label']

        bson_encoders = {
            date: lambda dt: dt if hasattr(dt, 'hour')
            else datetime(year=dt.year, month=dt.month, day=dt.day,
                          hour=0, minute=0, second=0)
        }

    class Config:
        title = 'Client'

    @classmethod
    def get_create_resource(cls):
        print('coucou')
