"""
TOT_PAR_LIM_CANT_PESO / TOT_PAR_LIM_VALOR
Computes invoice-level totals (quantity, net weight, capture value) from all
line items and writes them back to the invoice financials.

These totals are used downstream to enforce the SisExp limit parameters
(CantLimite, PesoLimite, ValorLimite — TODO when SisExp model is available).

Legacy equivalents
------------------
TOT_PAR_LIM_CANT_PESO:
  SELECT SUM(CantExpo), SUM(PesoNeto)
  FROM   QEqeMaq
  WHERE  Consecutivo = <invoice.id>
  → stored in Loc:CantExpoLim, Loc:PesoNetoLim

TOT_PAR_LIM_VALOR:
  SELECT SUM(CostoUnitarioCaptura * CantExpo)
  FROM   QEqeMaq
  WHERE  Consecutivo = <invoice.id>
  → stored in Loc:ValorExpoLim
"""

from decimal import Decimal
from typing import List

from api.v1.modules.a76.invoices.models import InvoiceHeader
from api.v1.modules.a76.items.models import LineItem
from core.exceptions import ErrorCollector


def limit_weight(    
    lines: List[LineItem],    
) -> tuple[Decimal, Decimal]:
    """
    TOT_PAR_LIM_CANT_PESO
    Sums exported quantity and net weight across all line items and Returns the totals.

    Returns
    -------
    (total_quantity, total_net_weight)
    after the call.
    """
    total_qty = Decimal(0)
    total_net_weight = Decimal(0)

    for line in lines:
        if line.quantity is None:
            continue
        total_qty += line.quantity.quantity or Decimal(0)
        total_net_weight += line.quantity.net_weight or Decimal(0)

    return total_qty, total_net_weight


def limit_value(        
    lines: List[LineItem],    
) -> Decimal:
    """
    TOT_PAR_LIM_VALOR
    Sums (unit_cost_capture × quantity) across all line items and writes the
    result to ``invoice.financials.value_mn`` as the capture-based total value.

    Returns
    -------
    total_capture_value — also available on invoice.financials after the call.

    Note: the legacy field Loc:ValorExpoLim is only used to compare against
    SisExp limit parameters (TODO when SisExp model is available).
    """
    total_value = Decimal(0)

    for line in lines:
        if line.financial is None or line.quantity is None:
            continue
        capture = line.financial.unit_cost_capture or Decimal(0)
        qty = line.quantity.quantity or Decimal(0)
        total_value += capture * qty

    return total_value
