from datetime import datetime
from typing import Any

from pydantic import BaseModel, Field


# Um cliente nasce do push do Sabichão ao criar o cliente lá, e um `related` nasce
# de ser descoberto como sócio ou titular de alvará. Nenhum dos dois se cria à mão
# aqui — daí estarem no `CompanyUpdate` (para se poder reclassificar) e não no
# `CompanyCreate`.
MonitoringType = Field(pattern="^(internal|competitor|analysis)$")


class CompanyCreate(BaseModel):
    nif: str = Field(min_length=9, max_length=9, pattern="^[0-9]{9}$")
    legal_name: str
    trade_name: str | None = None
    cae: str | None = None
    address: str | None = None
    status: str | None = None
    monitored: bool = True
    monitoring_type: str = Field(default="internal", pattern="^(internal|competitor|analysis)$")


class CompanyUpdate(BaseModel):
    legal_name: str | None = None
    trade_name: str | None = None
    cae: str | None = None
    address: str | None = None
    status: str | None = None
    monitored: bool | None = None
    active: bool | None = None
    monitoring_type: str | None = Field(
        default=None, pattern="^(internal|competitor|analysis|client|related)$"
    )


class CompanyOut(BaseModel):
    id: str
    nif: str
    legal_name: str
    trade_name: str | None
    cae: str | None
    address: str | None
    status: str | None
    monitored: bool
    active: bool = True
    monitoring_type: str
    data_coverage_start: datetime | None
    data_coverage_end: datetime | None
    risk_score: int | None
    ptdata_fetched_at: datetime | None
    created_at: datetime
    updated_at: datetime
    # Derived via LEFT JOIN. alvara_number is the comma-separated list of
    # Alvará A sub-codes the company holds (e.g. "16A, 16B, 16C") when it
    # appears in the PSP roster. founded_date is the date of the
    # "Constituição de sociedade" publication when MJ has captured one —
    # immune to alvará renewals (unlike any date derived from PSP).
    alvara_number: str | None = None
    founded_date: datetime | None = None


class RaciusImportItem(BaseModel):
    nif: str = Field(min_length=9, max_length=9, pattern="^[0-9]{9}$")
    legal_name: str
    status: str | None = None  # e.g. 'encerrada', 'insolvência', 'revitalização'
    monitoring_type: str = Field(default="competitor", pattern="^(competitor|analysis)$")


class RaciusImportResult(BaseModel):
    inserted: list[str]  # NIFs
    skipped: list[dict[str, str]]  # {nif, reason}
    total_scheduled_backfills: int


class NifLookup(BaseModel):
    nif: str
    valid: bool
    source: str
    legal_name: str | None = None
    trade_name: str | None = None
    cae: str | None = None
    address: str | None = None
    status: str | None = None
    raw: dict[str, Any] | None = None
