from typing import List

from sqlalchemy.orm import Session

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


def assign_no_discharges_items(
    lines: List[LineItem],
    errors: ErrorCollector,
) -> None:
    """
    ASIGNA_NODESCARGA_PARTIDAS
    Sets ``discharge = False`` on every line item of the invoice.
    Used exclusively by invoice type NODES (no discharge).

    Legacy equivalent
    -----------------
    UPDATE QEqeMaq SET Descarga = 0
    FROM   QEqeMaq
    WHERE  Consecutivo = <invoice.id>
    """
    try:
        for line in lines:
            line.fa_data.discharge = False
    except Exception as exc:
        errors.add_error(
            field="items.discharge",
            message="Error al asignar No-Descarga en las partidas de exportación.",
            solution=["Verifique la integridad de las partidas de la factura."],
            code="ASSIGN_NO_DISCHARGE_ITEMS_ERROR",
            value=str(exc),
        )


def assign_no_discharges_series(
    db: Session,
    lines: List[LineItem],
    errors: ErrorCollector,
) -> None:
    """
    ASIGNA_NODESCARGA_SERIES
    Sets ``marca = False`` on every ``Serie`` row whose parent ``LineItem``
    has ``discharge = False`` (or ``discharge`` is ``None``).

    Legacy equivalent
    -----------------
    UPDATE QSeriesExpo
    SET    Marca = 0
    FROM   QSeriesExpo  SerExpo
    LEFT JOIN QEqeMaq   EqiPex
           ON  EqiPex.Consecutivo = SerExpo.Consecutivo
           AND EqiPex.LineaExpo   = SerExpo.LineaExpo
    WHERE  SerExpo.Consecutivo = <invoice.id>
      AND  EqiPex.Descarga = 0
    """
    try:
        no_discharge_line_ids = {
            line.id
            for line in lines
            if not line.fa_data.discharge
        }

        if not no_discharge_line_ids:
            return

        (
            db.query(Serie)
            .filter(Serie.line_item_id.in_(no_discharge_line_ids))
            .update({"discharge": False}, synchronize_session="fetch")
        )
    except Exception as exc:
        errors.add_error(
            field="series.discharge",
            message="Error al asignar No-Descarga en las series de exportación.",
            solution=["Verifique la integridad de las series de la factura."],
            code="ASSIGN_NO_DISCHARGE_SERIES_ERROR",
            value=str(exc),
        )