"""Esquemas Pydantic para a coleção `empresas-dados`."""

from __future__ import annotations

from typing import List, Literal, Optional

from pydantic import AliasChoices, BaseModel, ConfigDict, Field, constr


class EmpresasDadosBase(BaseModel):
    """Campos compartilhados entre criação e atualização de empresas-dados."""

    cnpj: constr(strip_whitespace=True, min_length=1, max_length=32) = Field(
        ...,
        description="CNPJ da empresa (com ou sem máscara).",
        validation_alias=AliasChoices("cnpj"),
    )
    razaoSocial: constr(strip_whitespace=True, min_length=1, max_length=255) = Field(
        ...,
        description="Razão social cadastrada.",
        validation_alias=AliasChoices("razaoSocial", "razao-social"),
        serialization_alias="razaoSocial",
    )
    nomeFantasia: Optional[constr(strip_whitespace=True, max_length=255)] = Field(
        None,
        description="Nome fantasia da empresa.",
        validation_alias=AliasChoices("nomeFantasia", "nome-fantasia"),
        serialization_alias="nomeFantasia",
    )
    naturezaJuridica: Optional[constr(strip_whitespace=True, max_length=255)] = Field(
        None,
        description="Natureza jurídica informada pela Receita.",
        validation_alias=AliasChoices("naturezaJuridica", "natureza-juridica"),
        serialization_alias="naturezaJuridica",
    )
    porte: Optional[constr(strip_whitespace=True, max_length=100)] = Field(
        None,
        description="Porte da empresa (ex.: MEI, EPP, Demais).",
        validation_alias=AliasChoices("porte"),
    )
    capitalSocial: Optional[float] = Field(
        None,
        description="Capital social declarado.",
        validation_alias=AliasChoices("capitalSocial", "capital-social"),
        serialization_alias="capitalSocial",
    )
    telefone: Optional[constr(strip_whitespace=True, max_length=50)] = Field(
        None,
        description="Telefone principal da empresa.",
        validation_alias=AliasChoices("telefone"),
    )
    email: Optional[constr(strip_whitespace=True, max_length=255)] = Field(
        None,
        description="E-mail de contato principal.",
        validation_alias=AliasChoices("email"),
    )
    atividadePrincipal: Optional[constr(strip_whitespace=True, max_length=255)] = Field(
        None,
        description="Descrição da atividade econômica principal.",
        validation_alias=AliasChoices("atividadePrincipal", "atividade-principal-desc"),
        serialization_alias="atividadePrincipal",
    )
    atividadePrincipalCodigo: Optional[constr(strip_whitespace=True, max_length=32)] = Field(
        None,
        description="Código CNAE da atividade principal.",
        validation_alias=AliasChoices("atividadePrincipalCodigo", "atividade-principal-codigo"),
        serialization_alias="atividadePrincipalCodigo",
    )
    tipo: Optional[constr(strip_whitespace=True, max_length=50)] = Field(
        None,
        description="Tipo de inscrição (ex.: MATRIZ/ FILIAL).",
        validation_alias=AliasChoices("tipo"),
    )
    situacao: Optional[constr(strip_whitespace=True, max_length=100)] = Field(
        None,
        description="Situação cadastral da empresa.",
        validation_alias=AliasChoices("situacao"),
    )
    abertura: Optional[constr(strip_whitespace=True, max_length=50)] = Field(
        None,
        description="Data de abertura no formato AAAA-MM-DD ou similar.",
        validation_alias=AliasChoices("abertura", "data-abertura"),
        serialization_alias="abertura",
    )
    enderecoId: Optional[constr(strip_whitespace=True, min_length=1)] = Field(
        None,
        description="Identificador do endereço relacionado na coleção 'enderecos'.",
        validation_alias=AliasChoices("enderecoId", "enderecoID"),
        serialization_alias="enderecoId",
    )
    tipoFrete: Optional[Literal["gratis", "fixo", "por_km"]] = Field(
        default="fixo",
        description="Modelo de cobrança de frete para a empresa.",
        validation_alias=AliasChoices("tipoFrete", "tipo-frete"),
        serialization_alias="tipoFrete",
    )
    taxaEntrega: Optional[float] = Field(
        default=None,
        description="Valor fixo cobrado por entrega quando tipoFrete='fixo'.",
        validation_alias=AliasChoices("taxaEntrega", "taxa-entrega"),
        serialization_alias="taxaEntrega",
    )
    valorFreteKm: Optional[float] = Field(
        default=None,
        description="Valor por quilômetro quando tipoFrete='por_km'.",
        validation_alias=AliasChoices("valorFreteKm", "valor-frete-km"),
        serialization_alias="valorFreteKm",
    )
    raioEntregaKm: Optional[float] = Field(
        default=5.0,
        description="Raio máximo de entrega em quilômetros.",
        validation_alias=AliasChoices("raioEntregaKm", "raio-entrega-km"),
        serialization_alias="raioEntregaKm",
    )
    latitude: Optional[float] = Field(
        default=None,
        description="Latitude derivada via geocodificação do endereço.",
        validation_alias=AliasChoices("latitude"),
    )
    longitude: Optional[float] = Field(
        default=None,
        description="Longitude derivada via geocodificação do endereço.",
        validation_alias=AliasChoices("longitude"),
    )


class EmpresasDadosCreate(EmpresasDadosBase):
    """Payload para criar um documento em `empresas-dados`."""

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "cnpj": "12345678901323",
                "razao-social": "NANDO's",
                "nome-fantasia": "NANDO",
                "data-abertura": "2000-11-30",
                "situacao": "ativa",
                "natureza-juridica": "Sociedade Limitada",
                "porte": "Media",
                "capital-social": 100000.0,
                "telefone": "16987654321",
                "email": "andre.fr93@gmail.com",
                "atividade-principal-codigo": "47.11-3-01",
                "atividade-principal-desc": "Comércio varejista de mercadorias",
                "enderecoID": "68e7bf322aea078d2a05",
                "tipo-frete": "fixo",
                "taxa-entrega": 5.0,
                "valor-frete-km": 0.5,
                "raio-entrega-km": 50,
                "latitude": -23.5613,
                "longitude": -46.6564,
            }
        }
    )


class EmpresasDadosCreateEnvelope(BaseModel):
    """Aceita o payload no formato bruto do Appwrite com o campo `data`."""

    documentId: Optional[str] = Field(
        default=None,
        alias="documentId",
        description="ID opcional do documento; usa 'unique()' por padrão.",
    )
    data: EmpresasDadosCreate

    model_config = ConfigDict(
        populate_by_name=True,
        json_schema_extra={
            "example": {
                "documentId": "unique()",
                "data": {
                    "cnpj": "12345678901323",
                    "razao-social": "NANDO's",
                    "nome-fantasia": "NANDO",
                    "data-abertura": "2000-11-30",
                    "situacao": "ativa",
                    "natureza-juridica": "Sociedade Limitada",
                    "porte": "Media",
                "capital-social": 100000.0,
                    "telefone": "16987654321",
                    "email": "andre.fr93@gmail.com",
                    "atividade-principal-codigo": "47.11-3-01",
                    "atividade-principal-desc": "Comércio varejista de mercadorias",
                    "enderecoID": "68e7bf322aea078d2a05",
                    "tipo-frete": "fixo",
                    "taxa-entrega": 5.0,
                    "valor-frete-km": 0.5,
                    "raio-entrega-km": 50,
                    "latitude": -23.5613,
                    "longitude": -46.6564,
                },
            }
        },
    )


class EmpresasDadosUpdate(BaseModel):
    """Payload para atualização parcial de `empresas-dados`."""

    cnpj: Optional[constr(strip_whitespace=True, min_length=1, max_length=32)] = None
    razaoSocial: Optional[constr(strip_whitespace=True, min_length=1, max_length=255)] = None
    nomeFantasia: Optional[constr(strip_whitespace=True, max_length=255)] = None
    naturezaJuridica: Optional[constr(strip_whitespace=True, max_length=255)] = None
    porte: Optional[constr(strip_whitespace=True, max_length=100)] = None
    capitalSocial: Optional[float] = None
    telefone: Optional[constr(strip_whitespace=True, max_length=50)] = None
    email: Optional[constr(strip_whitespace=True, max_length=255)] = None
    atividadePrincipal: Optional[constr(strip_whitespace=True, max_length=255)] = None
    atividadePrincipalCodigo: Optional[constr(strip_whitespace=True, max_length=32)] = None
    tipo: Optional[constr(strip_whitespace=True, max_length=50)] = None
    situacao: Optional[constr(strip_whitespace=True, max_length=100)] = None
    abertura: Optional[constr(strip_whitespace=True, max_length=50)] = None
    enderecoId: Optional[constr(strip_whitespace=True, min_length=1)] = None
    tipoFrete: Optional[Literal["gratis", "fixo", "por_km"]] = None
    taxaEntrega: Optional[float] = None
    valorFreteKm: Optional[float] = None
    raioEntregaKm: Optional[float] = None
    latitude: Optional[float] = None
    longitude: Optional[float] = None

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "nomeFantasia": "Save In Med Loja Centro",
                "telefone": "(11) 4000-0000",
                "situacao": "INATIVA",
            }
        }
    )


class EmpresasDadosOut(BaseModel):
    """Representação de saída para documentos de `empresas-dados`."""

    id: str = Field(..., description="Identificador do documento no Appwrite.")
    cnpj: Optional[str] = Field(None, description="CNPJ cadastrado.")
    razaoSocial: Optional[str] = Field(None, description="Razão social armazenada.")
    nomeFantasia: Optional[str] = Field(None, description="Nome fantasia armazenado.")
    naturezaJuridica: Optional[str] = None
    porte: Optional[str] = None
    capitalSocial: Optional[float | str] = None
    telefone: Optional[str] = None
    email: Optional[str] = None
    atividadePrincipal: Optional[str] = None
    atividadePrincipalCodigo: Optional[str] = None
    tipo: Optional[str] = None
    situacao: Optional[str] = None
    abertura: Optional[str] = None
    enderecoId: Optional[str] = Field(
        default=None,
        description="Identificador do endereço relacionado, quando definido.",
    )
    tipoFrete: Optional[str] = Field(
        default=None, description="Modelo de cobrança de frete configurado."
    )
    taxaEntrega: Optional[float] = Field(
        default=None, description="Valor fixo de entrega quando aplicável."
    )
    valorFreteKm: Optional[float] = Field(
        default=None, description="Valor por quilômetro para frete variável."
    )
    raioEntregaKm: Optional[float] = Field(
        default=None, description="Raio máximo de entrega em quilômetros."
    )
    latitude: Optional[float] = Field(
        default=None, description="Latitude do endereço da empresa."
    )
    longitude: Optional[float] = Field(
        default=None, description="Longitude do endereço da empresa."
    )
    createdAt: Optional[str] = Field(
        default=None,
        description="Timestamp de criação fornecido pelo Appwrite.",
    )
    updatedAt: Optional[str] = Field(
        default=None,
        description="Timestamp da última atualização fornecido pelo Appwrite.",
    )

    model_config = ConfigDict(
        populate_by_name=True,
        json_schema_extra={
            "example": {
                "id": "emp-dados_123",
                "cnpj": "27865757000102",
                "razaoSocial": "Save In Med Comércio de Medicamentos LTDA",
                "nomeFantasia": "Save In Med",
                "naturezaJuridica": "206-2 - Sociedade Empresária Limitada",
                "porte": "DEMAIS",
                "capitalSocial": "50000.00",
                "telefone": "(11) 3000-0000",
                "email": "contato@saveinmed.com.br",
                "atividadePrincipal": "Comércio varejista de produtos farmacêuticos",
                "atividadePrincipalCodigo": "47.71-7-01",
                "situacao": "ATIVA",
                "abertura": "2010-05-10",
                "enderecoId": "addr_123",
                "tipoFrete": "fixo",
                "taxaEntrega": 7.0,
                "valorFreteKm": None,
                "raioEntregaKm": 5.0,
                "latitude": -23.5613,
                "longitude": -46.6564,
                "createdAt": "2024-10-01T10:00:00.000Z",
                "updatedAt": "2024-10-02T11:00:00.000Z",
            }
        },
    )


class PaginatedEmpresasDados(BaseModel):
    """Envelope de paginação simples para respostas da coleção."""

    items: List[EmpresasDadosOut]
    total: int

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "items": [
                    {
                        "id": "emp-dados_123",
                        "cnpj": "27865757000102",
                        "razaoSocial": "Save In Med Comércio de Medicamentos LTDA",
                        "nomeFantasia": "Save In Med",
                        "situacao": "ATIVA",
                        "createdAt": "2024-10-01T10:00:00.000Z",
                        "updatedAt": "2024-10-02T11:00:00.000Z",
                    }
                ],
                "total": 1,
            }
        }
    )
