from typing import List, Optional, Union, Any
from pydantic import BaseModel, field_validator

class ClienteSchema(BaseModel):
    header: str
    nombre: str
    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] = ""

    @field_validator('direccion', 'nombre', 'tax_id', mode='before')
    @classmethod
    def prevent_none(cls, v):
        return v or ""

class FacturaSchema(BaseModel):
    numero: str
    fecha: str
    tipo_cambio: Union[float, str]
    moneda: str
    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 = ""
    aduana: str = ""
    destino: str = ""
    observaciones: str = ""

class PartidaSchema(BaseModel):
    numero_parte: str
    descripcion: str
    fraccion: str
    fraccion_americana: Optional[str] = ""
    origen: str

    advalorem:Optional[str] = ""
    preferencia:Optional[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]
    peso_neto_lbs: Union[float, str] = 0.0
    peso_bruto_lbs: Union[float, str] = 0.0
    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]
    peso_neto_total_lbs: Union[float, str] = 0.0
    peso_bruto_total_lbs: Union[float, str] = 0.0
    valor_total_total: Union[float, str] = ""
    valor_total_dolares: Union[float, str] = ""

class PackingListSchema(BaseModel):
    cliente_proveedor: ClienteSchema
    cliente_vendido: ClienteSchema
    cliente_enviado: ClienteSchema
    factura: FacturaSchema
    partidas: List[PartidaSchema]
    totales: TotalesSchema
    logo_b64: Optional[str] = None

