from decimal import Decimal
from typing import List, Optional, Union
from pydantic import BaseModel, field_validator


class ClienteSchema(BaseModel):
    header: str
    nombre: str
    # Ponemos valor por defecto "" y permitimos que sea opcional
    direccion: Optional[str] = "" 
    num_exterior: Optional[str] = ""
    num_interior: Optional[str] = ""
    colonia: Optional[str] = ""
    codigo_postal: Optional[str] = ""
    ciudad: Optional[str] = ""
    estado: Optional[str] = ""
    pais: Optional[str] = ""
    tax_id: Optional[str] = ""
    programa: Optional[str] = ""
    autorizacion: Optional[str] = ""
    prosec: Optional[str] = ""
    reg_emp: Optional[str] = ""
    cert: Optional[str] = ""

    # Si llega un None, lo convertimos en "" automáticamente
    @field_validator('direccion', 'nombre', 'tax_id', mode='before')
    @classmethod
    def prevent_none(cls, v):
        return v or ""

class FacturaSchema(BaseModel):
    numero: str
    titulo_documento: str = "Factura de Importacion"  # Titulo dinámico basado en document_type
    fecha: str
    tipo_cambio: float
    moneda: str
    # Campos de aduanas (Opcionales por si A76 aún no los tiene)
    pedimento: str = ""
    clave_pedimento: str = ""
    remesa: str = ""
    acuse_electronico: str = ""
    agente_aduanal: str = ""
    patente: str = ""
    precinto: str = ""
    regimen: str = ""
    transportista: str = ""
    scac: str = ""
    caat: str = ""
    incoterm: str = ""
    transporte: str = ""
    num_transporte: str = ""
    placas: str = ""
    placas_remolque: str = ""
    licencia_conductor: str = ""
    caat: str = ""
    scac: str = ""
    aduana: str = ""
    destino: str = ""
    observaciones: str = ""

class PartidaSchema(BaseModel):
    numero_parte: str
    descripcion: str
    fraccion: str
    origen: str

    advalorem:Optional[str] = ""
    preferencia:Optional[str] = ""
    
    marca: Optional[str] = ""
    modelo: Optional[str] = ""
    series: List[str] = []

    cantidad_importacion: Union[float, str]
    unidad_medida: str
    cantidad_bultos: int
    clave_bultos: str
    peso_neto: Union[float, str]
    peso_bruto: Union[float, str]
    valor_costo_unitario: Union[float, str]
    valor_total: Union[float, str]

class TotalesSchema(BaseModel):
    cantidad_total: Union[float, str]
    bultos_total: int
    clave_bultos: str = ""
    peso_neto_total: Union[float, str]
    peso_bruto_total: Union[float, str]
    valor_total_total: Union[float, str]
    valor_total_dolares: Union[float, str]

class FacturaImportacionCompleta(BaseModel):
    cliente_proveedor: ClienteSchema
    cliente_vendido: ClienteSchema
    cliente_enviado: ClienteSchema
    factura: FacturaSchema
    partidas: List[PartidaSchema]
    totales: TotalesSchema