"""Paridad del catálogo de tipos de documento entre el CRM y EFC.

``EFC_DOC_TYPES`` del CRM tiene que ser **exactamente** el juego de claves de
``TIPOS_DOCUMENTO_CRM`` de ``api/record/views_integrations_crm.py`` en EFC. La lista está duplicada
a mano en dos repos con despliegue independiente, y este archivo es lo único que la mantiene
honesta: si alguien agrega un tipo de un solo lado, esto se pone rojo **antes** de que un documento
se rechace en producción con ``tipo_invalido``.

El juego esperado va escrito **literal** aquí y no derivado de ``doc_types.py``, porque una prueba
que se lo pregunte al mismo módulo que valida no prueba nada: pasaría con cualquier cambio.
"""

from api.v1.modules.crm.expediente_gateway.doc_types import EFC_DOC_TYPES, is_valid_doc_type

# Copia literal de las claves de TIPOS_DOCUMENTO_CRM (EFC, fase 3 del ticket T2026-08-046).
# Al cambiar EFC, se cambia AQUÍ y el rojo obliga a mirar los dos lados.
CLAVES_EN_EFC = {
    # crm.documents — DOC_TYPES de frontend/src/lib/api/crm/format.ts
    "constancia_fiscal",
    "acta_constitutiva",
    "identificacion",
    "comprobante_domicilio",
    "contrato",
    "presentacion",
    "certificacion",
    "licencia",
    "convenio",
    "tarifario",
    # ops.shipment_documents — SHIPMENT_DOC_TYPES del mismo archivo
    "MBL",
    "HBL",
    "MAWB",
    "HAWB",
    "CMR",
    "factura_comercial",
    "packing_list",
    "carta_encomienda",
    "carta_garantia",
    "certificado_permiso",
    # fin.invoices
    "factura_venta",
    # 'otro' existe en AMBAS listas del CRM y significa lo mismo: una sola entrada
    "otro",
}


def test_el_catalogo_del_crm_es_identico_al_de_efc():
    faltan_en_crm = CLAVES_EN_EFC - EFC_DOC_TYPES
    sobran_en_crm = EFC_DOC_TYPES - CLAVES_EN_EFC
    assert not faltan_en_crm, f"EFC acepta tipos que el CRM no conoce: {sorted(faltan_en_crm)}"
    assert not sobran_en_crm, (
        f"El CRM mandaría tipos que EFC va a rechazar con tipo_invalido: {sorted(sobran_en_crm)}"
    )


def test_son_exactamente_veintidos():
    """El número está en el ticket. Si cambia, es un cambio de contrato entre dos repos."""
    assert len(EFC_DOC_TYPES) == 22


def test_no_hay_duplicados_entre_las_tres_fuentes():
    """``otro`` está en las dos listas del CRM y debe colapsar a UNA entrada.

    Un ``frozenset`` lo colapsa solo; la prueba está para que una futura refactorización a lista o
    a tupla no reintroduzca el duplicado en silencio.
    """
    from api.v1.modules.crm.expediente_gateway import doc_types

    todas = (
        doc_types._TIPOS_DOCUMENTOS_CLIENTE
        + doc_types._TIPOS_DOCUMENTOS_EMBARQUE
        + doc_types._TIPOS_FACTURACION
        + doc_types._TIPOS_COMUNES
    )
    assert len(todas) == len(set(todas))


def test_un_tipo_fuera_del_catalogo_se_rechaza():
    """El CRM valida ANTES de gastar un viaje de red, y evita que un typo cree un DocumentType
    basura en el catálogo GLOBAL de EFC, que comparten todas las organizaciones."""
    assert is_valid_doc_type("MBL") is True
    assert is_valid_doc_type("mbl") is False  # sensible a mayúsculas, como el catálogo de EFC
    assert is_valid_doc_type("factura_de_venta") is False  # typo de 'factura_venta'
    assert is_valid_doc_type("") is False
    assert is_valid_doc_type(None) is False
