"""
DTOs (Data Transfer Objects) para módulo de clases SCAII y SCAF
Reemplaza schemas.py siguiendo enfoque DDD y estilo NestJS
"""

from datetime import datetime
from decimal import Decimal
from typing import Optional

from pydantic import BaseModel, ConfigDict, Field


class ClassCreateDTO(BaseModel):
    """DTO para crear una clase"""

    class_code: str = Field(..., max_length=8, description="Class code")
    description_es: str = Field(
        ..., max_length=500, description="Description in Spanish (required)"
    )
    description_en: Optional[str] = Field(
        None, max_length=500, description="Description in English"
    )
    material_key: str = Field(
        ...,
        max_length=10,
        description="Material key - Fixed Asset Type (required)",
    )
    unit_of_measure: str = Field(
        ..., max_length=5, description="Unit of measure - U.M. comercial (required)"
    )
    fraction: str = Field(
        ..., max_length=20, description="Mexican tariff fraction (required)"
    )
    us_fraction: Optional[str] = Field(
        None, max_length=16, description="US tariff fraction"
    )
    sub_key: Optional[str] = Field(
        None, max_length=5, description="Sub classification key"
    )
    physical_review: Optional[int] = Field(
        None, description="Physical review indicator"
    )
    iva_exempt_fraction: Optional[str] = Field(
        None, max_length=4, description="IVA exempt fraction"
    )
    is_active: Optional[bool] = Field(
        True, description="Indicates if the class is active (default: true)"
    )

    class Config:
        from_attributes = True


class ClassCreateDTOFA(ClassCreateDTO):
    """DTO para crear una clase de activo fijo (clase base + extensión FA)"""
    
    # Campos específicos de activos fijos (a24.fa_classes)
    import_tariff_code: Optional[str] = Field(
        None, max_length=10, description="Código de fracción de importación"
    )
    import_tariff_type: Optional[str] = Field(
        None, max_length=6, description="Tipo de fracción de importación"
    )
    export_tariff_code: Optional[str] = Field(
        None, max_length=10, description="Código de fracción de exportación"
    )
    export_tariff_type: Optional[str] = Field(
        None, max_length=6, description="Tipo de fracción de exportación"
    )
    depreciation_rate: Optional[Decimal] = Field(
        None, ge=0, le=100, description="Tasa de depreciación anual (%)"
    )
    fda_code: Optional[str] = Field(
        None, max_length=20, description="Código FDA"
    )
    eccn_code: Optional[str] = Field(
        None, max_length=20, description="Código ECCN"
    )
    class_enabled: Optional[bool] = Field(
        True, description="Indica si la clase está habilitada"
    )
    is_active: Optional[bool] = Field(
        True, description="Indicates if the class is active (default: true)"
    )

    class Config:
        from_attributes = True


class ClassUpdateDTO(BaseModel):
    """DTO para actualizar una clase"""

    class_code: Optional[str] = Field(
        None, max_length=8, description="Class code"
    )
    description_es: Optional[str] = Field(
        None, max_length=500, description="Description in Spanish"
    )
    description_en: Optional[str] = Field(
        None, max_length=500, description="Description in English"
    )
    material_key: Optional[str] = Field(
        None,
        max_length=10,
        description="Material key (homologated TIPOMAT/TIPOMATEQUIPO)",
    )
    unit_of_measure: Optional[str] = Field(
        None, max_length=5, description="Unit of measure (homologated UNIMEDIDA)"
    )
    fraction: Optional[str] = Field(
        None, max_length=20, description="Mexican tariff fraction"
    )
    us_fraction: Optional[str] = Field(
        None, max_length=16, description="US tariff fraction"
    )
    sub_key: Optional[str] = Field(
        None, max_length=5, description="Sub classification key"
    )
    physical_review: Optional[int] = Field(
        None, description="Physical review indicator"
    )
    iva_exempt_fraction: Optional[str] = Field(
        None, max_length=4, description="IVA exempt fraction"
    )
    is_active: Optional[bool] = Field(
        True, description="Indicates if the class is active (default: true)"
    )

    model_config = ConfigDict(from_attributes=True, extra='forbid')  # Explicitly forbid extra fields


class ClassResponseDTO(BaseModel):
    """DTO para respuesta de clase"""

    id: int
    tenant_id: int
    company_id: int
    class_code: str
    description_es: Optional[str] = None
    description_en: Optional[str] = None
    material_key: Optional[str] = None
    unit_of_measure: Optional[str] = None
    fraction: Optional[str] = None
    us_fraction: Optional[str] = None
    sub_key: Optional[str] = None
    physical_review: Optional[int] = None
    iva_exempt_fraction: Optional[str] = None
    is_active: Optional[bool] = None
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class ClassResponseDTOFA(ClassResponseDTO):
    """DTO para respuesta de clase de activo fijo (incluye campos FA)"""
    
    # Campos de a24.fa_classes
    fa_id: Optional[int] = None
    import_tariff_code: Optional[str] = None
    import_tariff_type: Optional[str] = None
    export_tariff_code: Optional[str] = None
    export_tariff_type: Optional[str] = None
    depreciation_rate: Optional[Decimal] = None
    fda_code: Optional[str] = None
    eccn_code: Optional[str] = None
    class_enabled: Optional[bool] = None

    model_config = ConfigDict(from_attributes=True)


class ClassBasicDTO(BaseModel):
    """DTO para información básica de clase"""

    class_code: str
    description_es: Optional[str] = None
    description_en: Optional[str] = None
    material_key: Optional[str] = None
    fraction: Optional[str] = None

    class Config:
        from_attributes = True


class ClassListDTO(BaseModel):
    """DTO para lista de clases"""

    classes: list[ClassBasicDTO]
    total: int
    page: int
    size: int

    class Config:
        from_attributes = True


class ClassSearchDTO(BaseModel):
    """DTO para búsqueda de clases"""

    class_code: Optional[str] = Field(None, description="Search by class code")
    description: Optional[str] = Field(None, description="Search in descriptions")
    material_key: Optional[str] = Field(None, description="Filter by material key")
    fraction: Optional[str] = Field(None, description="Filter by tariff fraction")
    physical_review: Optional[int] = Field(
        None, description="Filter by physical review indicator"
    )

    class Config:
        from_attributes = True


class ClassWithFADataResponse(BaseModel):
    """DTO para respuesta de clase con datos FA embebidos (para fixed-asset-classes)"""
    
    # Base class fields
    id: int
    tenant_id: int
    company_id: int
    class_code: str
    description_es: Optional[str] = None
    description_en: Optional[str] = None
    material_key: Optional[str] = None
    unit_of_measure: Optional[str] = None
    fraction: Optional[str] = None
    us_fraction: Optional[str] = None
    sub_key: Optional[str] = None
    physical_review: Optional[int] = None
    iva_exempt_fraction: Optional[str] = None
    created_at: datetime
    updated_at: datetime
    
    # FA-specific fields (embedded from a24.fa_classes)
    fa_class_id: Optional[int] = None
    import_tariff_code: Optional[str] = None
    import_tariff_type: Optional[str] = None
    export_tariff_code: Optional[str] = None
    export_tariff_type: Optional[str] = None
    depreciation_rate: Optional[Decimal] = None
    fda_code: Optional[str] = None
    eccn_code: Optional[str] = None
    class_enabled: Optional[bool] = None
    
    model_config = ConfigDict(from_attributes=True)


class ClassWithFADataPaginatedResponse(BaseModel):
    """Lista paginada de clases con datos FA (fixed-asset-classes)"""

    items: list[ClassWithFADataResponse]
    total: int
    page: int
    page_size: int

    model_config = ConfigDict(from_attributes=True)