"""
Carga de conjuntos FK para validación de import CSV de pedimentos.
Clarion: clave+regimen+tipo (CodePedimentoRegimen), aduana (CustomsSection), patente (CustomsBroker.license), existing_pedimento_keys.
Legacy: valid_client_ids, valid_regimes, valid_pedimento_codes. Cliente por short_name: short_name_to_id.
"""
from typing import Dict, Set, Tuple

from sqlalchemy.orm import Session


def _pedimento_key(year: str, customs_office: str, license_val: str, pedimento_number: str) -> str:
    """Clave única para identificar un pedimento (tenant/company se filtra en query)."""
    return f"{year}|{customs_office}|{license_val}|{pedimento_number}"


def load_pedimentos_fk_sets(
    session: Session, tenant_id: int, company_id: int
) -> Tuple[
    Set[int],
    Set[str],
    Set[str],
    Set[Tuple[str, str, str]],
    Set[str],
    Set[str],
    Set[str],
    Set[str],
    Dict[str, int],
]:
    """
    Carga todos los conjuntos FK para validación Clarion y legacy.
    Returns:
        valid_client_ids,
        valid_regimes,
        valid_pedimento_codes,
        valid_clave_regimen_tipo,  # (pedimento_code, regimen_code, type_code)
        valid_aduana_seccion,      # customs_code
        existing_pedimento_keys,   # key strings para actualizar
        valid_anexo22_claves,      # catálogo de transporte Anexo 22 (pedimento_transport_catalog.code)
        valid_patentes,            # CustomsBroker.license (tenant/company)
        short_name_to_id,          # short_name normalizado (upper) -> client id (primera aparición gana)
    """
    from api.v1.modules.a76.clients_and_providers.models import ClientProvider
    from api.v1.modules.a76.customs_brokers.models import CustomsBroker
    from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos
    from api.v1.modules.public.reference_data.code_pedimento_regimens.models import (
        CodePedimentoRegimen,
    )
    from api.v1.modules.public.reference_data.code_pedimento_regimens.seed import (
        seed as code_pedimento_regimens_seed,
    )
    from api.v1.modules.public.reference_data.customs_sections.models import CustomsSection
    from api.v1.modules.public.reference_data.pedimento_codes.models import PedimentoCode
    from api.v1.modules.public.reference_data.pedimento_regimens.models import RegimenPedimento
    from api.v1.modules.public.reference_data.pedimento_transport_catalog.models import (
        PedimentoTransportCatalog,
    )

    valid_client_ids: Set[int] = set()
    valid_regimes: Set[str] = set()
    valid_pedimento_codes: Set[str] = set()
    valid_clave_regimen_tipo: Set[Tuple[str, str, str]] = set()
    valid_aduana_seccion: Set[str] = set()
    existing_pedimento_keys: Set[str] = set()
    valid_anexo22_claves: Set[str] = set()
    valid_patentes: Set[str] = set()
    short_name_to_id: Dict[str, int] = {}

    for cp in (
        session.query(ClientProvider)
        .filter(
            ClientProvider.tenant_id == tenant_id,
            ClientProvider.company_id == company_id,
        )
        .order_by(ClientProvider.id)
        .all()
    ):
        valid_client_ids.add(cp.id)
        sn = (cp.short_name or "").strip()
        if sn:
            key = sn.upper()
            if key not in short_name_to_id:
                short_name_to_id[key] = cp.id

    for r in session.query(RegimenPedimento).all():
        valid_regimes.add(r.code)

    for pc in session.query(PedimentoCode).all():
        valid_pedimento_codes.add(pc.code)

    for cpr in session.query(CodePedimentoRegimen).all():
        # type_code puede ser None; Clarion usa I/E. Normalizar a mayúsculas para coincidir con CSV.
        t = (cpr.type_code or "").strip().upper()
        if t:
            valid_clave_regimen_tipo.add(
                (
                    (cpr.pedimento_code or "").strip().upper(),
                    (cpr.regimen_code or "").strip().upper(),
                    t,
                )
            )
    # Respaldo desde seed: evita desalineación temporal cuando el catálogo en BD
    # no ha sido re-sincronizado tras actualizar la semilla.
    for ped_code, reg_code, type_code in code_pedimento_regimens_seed:
        ped = (ped_code or "").strip().upper()
        reg = (reg_code or "").strip().upper()
        typ = (type_code or "").strip().upper()
        if ped and reg and typ:
            valid_clave_regimen_tipo.add((ped, reg, typ))

    for cs in session.query(CustomsSection).all():
        valid_aduana_seccion.add(cs.customs_code.strip())

    for tm in session.query(PedimentoTransportCatalog.code).all():
        if (tm[0] or "").strip():
            valid_anexo22_claves.add((tm[0] or "").strip().upper())

    for cb in (
        session.query(CustomsBroker)
        .filter(
            CustomsBroker.tenant_id == tenant_id,
            CustomsBroker.company_id == company_id,
        )
        .all()
    ):
        if (cb.license or "").strip():
            valid_patentes.add((cb.license or "").strip())

    for p in (
        session.query(
            Pedimentos.year,
            Pedimentos.customs_office,
            Pedimentos.license,
            Pedimentos.pedimento_number,
        )
        .filter(
            Pedimentos.tenant_id == tenant_id,
            Pedimentos.company_id == company_id,
        )
        .all()
    ):
        existing_pedimento_keys.add(
            _pedimento_key(
                (p.year or "").strip(),
                (p.customs_office or "").strip(),
                (p.license or "").strip(),
                (p.pedimento_number or "").strip(),
            )
        )

    return (
        valid_client_ids,
        valid_regimes,
        valid_pedimento_codes,
        valid_clave_regimen_tipo,
        valid_aduana_seccion,
        existing_pedimento_keys,
        valid_anexo22_claves,
        valid_patentes,
        short_name_to_id,
    )


def pedimento_key_from_parsed(
    year: str, customs_office: str, license_val: str, pedimento_number: str
) -> str:
    """Construye la clave para comparar con existing_pedimento_keys."""
    return _pedimento_key(year, customs_office, license_val, pedimento_number)
