"""
Enriquecimiento de partidas de exportación cargadas por CSV.
Aplica las mismas reglas que items/exports/validators (create + calculations):
hereda de línea de importación y calcula valores por currency; defaults de export.
"""
from sqlalchemy.orm import Session, joinedload

from api.v1.modules.a76.invoices.models import InvoiceHeader
from api.v1.modules.a76.classes.models import Class
from api.v1.modules.a76.parts.models import Part
from api.v1.modules.a24.fa.fa_item_lines.dto import FaLineItemCreateDTO

from api.v1.modules.a76.items.schemas import LineItemCreate
from api.v1.modules.a76.items.exports.validators.calculations import (
    calculate_values,
    apply_calculations,
)


def _ensure_nested(line_data: LineItemCreate) -> None:
    """Asegura que existan los objetos anidados para calculate_values y apply_calculations."""
    from api.v1.modules.a76.items.line_financials.schemas import LineFinancialCreate
    from api.v1.modules.a76.items.line_quantities.schemas import LineQuantityCreate
    from api.v1.modules.a76.items.line_customs.schemas import LineCustomCreate
    from api.v1.modules.a76.items.line_descriptions.schemas import LineDescriptionCreate

    if line_data.financial is None:
        line_data.financial = LineFinancialCreate()
    if line_data.quantity is None:
        line_data.quantity = LineQuantityCreate()
    if line_data.customs is None:
        line_data.customs = LineCustomCreate()
    if line_data.description is None:
        line_data.description = LineDescriptionCreate()
    if line_data.fa_data is None:
        line_data.fa_data = FaLineItemCreateDTO(is_subitem=False, contains_subitems=False)


def apply_export_defaults_and_calculations_for_csv(
    db: Session,
    line_data: LineItemCreate,
    tenant_id: int,
    company_id: int,
    line_number: int,
) -> bool:
    """
    Aplica defaults y cálculos de partida de exportación según reglas del proceso manual
    (copia desde línea de importación, currency, defaults has_fda_code, tax_payment, etc.).
    Se invoca tras armar LineItemCreate desde el CSV.
    Devuelve False si faltan factura/financials; True en caso contrario.
    """
    _ensure_nested(line_data)

    invoice: InvoiceHeader = (
        db.query(InvoiceHeader)
        .options(joinedload(InvoiceHeader.financials))
        .filter(
            InvoiceHeader.id == line_data.invoice_id,
            InvoiceHeader.tenant_id == tenant_id,
            InvoiceHeader.company_id == company_id,
        )
        .first()
    )
    if not invoice or not invoice.financials:
        return False

    part: Part | None = None
    if line_data.part_number_id:
        part = (
            db.query(Part)
            .filter(
                Part.id == line_data.part_number_id,
                Part.tenant_id == tenant_id,
                Part.company_id == company_id,
            )
            .first()
        )
    if part and line_data.description:
        # Fallback explícito: priorizar descripciones de parte para paridad manual.
        if not line_data.description.description_spanish and part.description_spanish:
            line_data.description.description_spanish = part.description_spanish
        if not line_data.description.description_english and part.description_english:
            line_data.description.description_english = part.description_english

    if not line_data.unit_of_measure and line_data.class_id:
        class_info = (
            db.query(Class)
            .filter(
                Class.id == line_data.class_id,
                Class.tenant_id == tenant_id,
                Class.company_id == company_id,
            )
            .first()
        )
        if class_info:
            line_data.unit_of_measure = class_info.unit_of_measure

    # Copia desde línea de importación y cálculos por currency (reglas manual)
    calculate_values(db, line_data, tenant_id, company_id)

    # Defaults: has_fda_code, tax_payment, payment_method, depreciation_date, descripciones
    apply_calculations(db, line_data, tenant_id, company_id, line_number)

    return True
