from typing import List
from html import unescape

from pydantic import BaseModel, Field, validator

from ..core.models import CrudDocument, RichtextMultiline, RichtextSingleline, DictionaryEntry


class PartyTemplate(BaseModel):
    entity_id: str = Field(
        foreignKey={
            "reference": {
                "resource": "entity",
                "schema": "Entity",
            }
        },
        default="",
        title="Partie"
    )
    part: str = Field(title="Rôle")
    representative_id: str = Field(
        foreignKey={
            "reference": {
                "resource": "entity",
                "schema": "Entity",
            }
        },
        default="",
        title="Représentant"
    )

    class Config:
        title = 'Partie'


def remove_html_tags(text):
    """Remove html tags from a string"""
    import re
    clean = re.compile('<.*?>')
    return re.sub(clean, '', text)


class ProvisionTemplate(CrudDocument):
    """
    Modèle de clause à décliner
    """

    name: str = Field(title="Nom")
    title: str = RichtextSingleline(title="Titre")
    label: str = ""
    body: str = RichtextMultiline(title="Corps")

    @validator("label", always=True)
    def generate_label(cls, v, values, **kwargs):
        return "{} - \"{}\"".format(values['name'], unescape(remove_html_tags(values['title'])))

    class Settings(CrudDocument.Settings):
        fulltext_search = ['name', 'title', 'body']

    class Config:
        title = 'Template de clause'


class ProvisionTemplateReference(BaseModel):
    provision_template_id: str = Field(
        foreignKey={
            "reference": {
                "resource": "template/provision",
                "schema": "ProvisionTemplate",
                "displayedFields": ['title', 'body']
            },
        },
        props={"parametrized": True},
        title="Template de clause"
    )

    class Config:
        title = 'Clause'


class ContractTemplate(CrudDocument):
    """
    Modèle de contrat à décliner
    """
    name: str = Field(title="Nom")
    title: str = Field(title="Titre")
    label: str = ""
    parties: List[PartyTemplate] = Field(default=[], title="Parties")
    provisions: List[ProvisionTemplateReference] = Field(
        default=[],
        props={"items-per-row": "1", "numbered": True},
        title="Clauses"
    )
    variables: List[DictionaryEntry] = Field(
        default=[],
        format="dictionary",
        title="Variables"
    )

    @validator("label", always=True)
    def generate_label(cls, v, values, **kwargs):
        return "{} - \"{}\"".format(values['name'], unescape(remove_html_tags(values['title'])))

    class Settings(CrudDocument.Settings):
        fulltext_search = ['name', 'title']

    class Config:
        title = 'Template de contrat'
