from typing import List

from sqlalchemy.orm import Session

from api.v1.modules.a76.general_catalogs.company.models import Company
from api.v1.modules.a76.general_catalogs.units_of_measure.models import UnitOfMeasure
from api.v1.modules.a76.items.models import LineItem
from api.v1.modules.a76.items.series.models import Serie
from api.v1.modules.a76.app_settings.service import AppSettingsService
from core.exceptions import ErrorCollector

# RFCs donde la validación de cantidad vs series únicamente aplica a PZA (paridad Clarion)
_RFC_EXCEPCION_PZA = {
    "IMS030409FZ0",
    "TOP140430PB6",
    "AMA7504258K2",
    "BZG111091T9",
}


def review_series(
    db: Session,
    line: LineItem,    
    company_rfc: str,
    tenant_id: str,
    company_id: str,
    errors: ErrorCollector,
) -> None:
    """
    Revisa la cantidad de series vs la cantidad a importar, por partida.

    Paridad: REVISA_CANT_SERIES (Clarion SCAII).

    Reglas:
    - Si la partida tiene LlevaSerie / has_serial activado:
        1. Si no existen registros de series → error SERIES_VACIAS.
        2. Si SisGen:CantvsCantSeries = 1:
           - Para RFC excepcionales: solo valida la coincidencia si UnidadMedida = 'PZA'.
           - Para el resto: valida siempre que count(series) != cantidad.
    """
    # Resolver RFC de la empresa una sola vez
    
    
    # Solo aplica a partidas que llevan serie
    if not (line.description and line.description.has_serial):
        return

    series_count = (
        db.query(Serie)
        .filter(Serie.line_item_id == line.id)
        .count()
    )

    if series_count == 0:
        errors.add_error(
            field=f"line[{line.line_number}].series",
            message="La opción de contiene series esta activada y no existen registros de Series.",
            solution=[
                "Desactivar la opción de Lleva series o registrar las series a esta partida."
            ],
            code="SERIES_VACIAS",
        )
        return

    # GNiv:CantSerievsCant = 0 → el bloque series > cantidad estaba comentado en Clarion original
    settings = AppSettingsService.get_resolved_settings(db, int(tenant_id), int(company_id))
    q_gen = settings.get("qsisgen", {})
    s_gen = settings.get("ssisgen", {})

    # Switch maestro: validarseries = 0 desactiva toda la validación de series (SSisGen/QSisGen)
    valida_series_global = int(q_gen.get("validarseries") or s_gen.get("validarseries", 0))
    if valida_series_global != 1:
        return

    valida_cant_series = int(q_gen.get("cantvscantseries") or s_gen.get("cantvscantseries", 0))

    if valida_cant_series != 1:
        return

    qty = line.quantity.quantity if line.quantity else None
    if qty is None:
        return

    # Determinar si se debe validar series
    validate_series = (
        series_count != qty and
        (company_rfc not in _RFC_EXCEPCION_PZA or line.unit_of_measure == "PZA")
    )

    if validate_series:
        errors.add_error(
            field=f"line[{line.line_number}].series",
            message="La Cantidad de Series No Coincide con la Cantidad de la Partida.",
            solution=[f"Nivelar las series de la Partida {line.line_number}."],
            code="SERIES_VS_CANT",
        )

    
    

   
    