from datetime import datetime
from decimal import Decimal
from typing import List, Optional
from pydantic import BaseModel, Field, ConfigDict

# --- SUB-DTO: DATOS ADUANALES (FaData) ---
class FaDataDTO(BaseModel):
    origin_country: Optional[str] = None
    sector: Optional[str] = None
    fraction_type: Optional[str] = None

    model_config = ConfigDict(from_attributes=True)

# --- SUB-DTO: DATOS DE INVENTARIO Y COSTEO (InvData) ---
class InvDataDTO(BaseModel):
    part_type: Optional[str] = None
    material_type: Optional[str] = None
    reference_number: Optional[str] = None
    flex_reference_number: Optional[str] = None
    equivalent_uom: Optional[str] = None
    conversion_factor: Optional[Decimal] = None
    stock_uom: Optional[str] = None
    alternate_uom: Optional[str] = None
    conversion_uom: Optional[str] = None
    added_value: Optional[Decimal] = None
    added_value_type: Optional[str] = None
    assigned_client: Optional[str] = None
    supplier_code: Optional[str] = None
    is_textile: Optional[str] = None
    bom_version: Optional[int] = None
    is_repair: Optional[str] = None
    is_hazardous: Optional[str] = None
    emergency_number: Optional[str] = None
    danger_class: Optional[str] = None
    packaging_group: Optional[str] = None
    width: Optional[str] = None
    thickness: Optional[str] = None
    specification: Optional[str] = None
    
    # Desglose de Costos (Anexo 24 - Valor Agregado)
    total_value: Optional[Decimal] = None
    direct_labor: Optional[Decimal] = None
    general_expenses: Optional[Decimal] = None
    total_expenses: Optional[Decimal] = None
    depreciation: Optional[Decimal] = None
    tooling: Optional[Decimal] = None
    material_consumed: Optional[Decimal] = None
    profit: Optional[Decimal] = None
    
    # Fracciones adicionales y TLCAN/T-MEC
    us_fraction_alt: Optional[str] = None
    ca_fraction: Optional[str] = None
    ad_valorem_us: Optional[Decimal] = None
    nafta_result: Optional[str] = None
    nafta_percentage: Optional[Decimal] = None
    dta: Optional[str] = None
    dtb: Optional[str] = None
    dtg: Optional[str] = None

    model_config = ConfigDict(from_attributes=True)


class PartBase(BaseModel):
    client_id: int
    part_number: str = Field(..., max_length=70)
    commercial_part_number: Optional[str] = None
    
    description_spanish: Optional[str] = None
    description_english: Optional[str] = None
    part_class: Optional[str] = None
    unit_of_measure: Optional[str] = "PZ"
    
    unit_cost: Optional[Decimal] = None
    currency_key: Optional[str] = None
    currency_type: Optional[str] = None
    
    unit_weight: Optional[Decimal] = None
    weight_type: Optional[str] = None
    
    fraction: Optional[str] = None
    us_fraction: Optional[str] = None
    
    # Regulatorios
    fda_key: Optional[str] = None
    fcc_key: Optional[str] = None
    license_code: Optional[str] = None
    eccn: Optional[str] = None
    export_code: Optional[str] = None
    exclusion_symbol: Optional[str] = None
    
    is_active: bool = True
    part_photo: Optional[str] = None

    # Anidados
    fa_data: Optional[FaDataDTO] = None
    inv_data: Optional[InvDataDTO] = None

# --- CREACIÓN ---
class PartCreateDTO(PartBase):
    # Opcional para que lo tome de la URL si no viene en el body
    company_id: Optional[int] = None 

# --- ACTUALIZACIÓN ---
class PartUpdateDTO(PartBase):
    client_id: Optional[int] = None
    part_number: Optional[str] = None
    # Todo opcional para PATCH
    pass

# --- RESPUESTA ---
class PartResponseDTO(PartBase):
    id: int
    tenant_id: int
    company_id: int
    creation_date: Optional[int] = None
    modification_date_iso: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)

# --- BÁSICO (Para listados ligeros) ---
class PartBasicDTO(BaseModel):
    id: int
    part_number: str
    description_spanish: Optional[str] = None
    fraction: Optional[str] = None
    is_active: bool
    
    model_config = ConfigDict(from_attributes=True)

# --- LISTADO PAGINADO ---
class PartListResponseDTO(BaseModel):
    items: List[PartResponseDTO]
    total: int
    page: int
    page_size: int
    pages: int

