"""
Configuración de plantilla CSV para Agentes Aduanales (EstructuraCatAgenteAduanal.xls).
Layout Clarion: A=TIPO, B=CLAVE AADUANAL, C=PATENTE, D=NOMBRE, E=RFC, F=DIRECCION, G=CODIGO POSTAL,
H=CIUDAD, I=ESTADO, J=PAIS, K=TELEFONO, L=NUMERO FAX, M=CORREO ELECTRONICO, N=CURP, O=COL_EXTRA (desfase).
Encabezado ejemplo: "TIPO(MEX=Mexicano,AME=AMERICANO)",CLAVE AADUANAL,PATENTE,NOMBRE,RFC,...
Solo se leen columnas definidas aquí; el resto se ignora.
"""

from typing import Dict, List, Any, Optional

from ..common.cell_value import cell_to_str
from ..common.csv_hint_inject import inject_max_char_hints_into_columns, merge_enum_hint_before_max
from ..common.inject_csv_labels_en import inject_en_labels_into_template_columns
from ..common.template_locale import merge_download_header_into_lookup, merge_labels_into_lookup
from .csv_max_chars_for_headers import CUSTOMS_BROKERS_CSV_MAX_CHARS

TEMPLATE_COLUMNS: Dict[str, List[Dict[str, Any]]] = {
    "customs_brokers": [
        # Col A - TIPO (MEX/Mexicano, AME/Americano)
        {"canonical": "TIPO", "aliases": ["TIPO(MEX=Mexicano,AME=AMERICANO)"]},
        # Col B - Clave agente aduanal (máx 5)
        {"canonical": "CLAVE", "aliases": ["BROKER_KEY", "CLAVE AGENTE", "CLAVE AADUANAL", "CLAVE ADUANAL", "ID"]},
        # Col C - Patente / Licencia (obligatoria si TIPO=MEX)
        {"canonical": "LICENCIA", "aliases": ["PATENTE", "LICENSE"]},
        # Col D - Nombre
        {"canonical": "NOMBRE", "aliases": ["NOMBRE COMPLETO", "RAZON SOCIAL"]},
        # Col E - RFC (máx 30)
        {"canonical": "RFC", "aliases": ["TAX_ID", "TAXID"]},
        # Col F - Dirección
        {"canonical": "DIRECCION", "aliases": ["DOMICILIO"]},
        # Col G - Código postal
        {"canonical": "CODIGO POSTAL", "aliases": ["CODIGOPOSTAL", "CP", "C.P."]},
        # Col H - Ciudad
        {"canonical": "CIUDAD"},
        # Col I - Estado
        {"canonical": "ESTADO"},
        # Col J - País (clave M3)
        {"canonical": "PAIS", "aliases": ["COUNTRY"]},
        # Col K - Teléfono
        {"canonical": "TELEFONO", "aliases": ["PHONE", "TEL"]},
        # Col L - Fax
        {"canonical": "FAX", "aliases": ["NUMERO FAX"]},
        # Col M - Email
        {"canonical": "EMAIL", "aliases": ["CORREO", "E-MAIL", "CORREO ELECTRONICO"]},
        # Col N - CURP / Personal ID (máx 19)
        {"canonical": "PERSONAL_ID", "aliases": ["PERSONALID", "ID PERSONAL", "CURP"]},
        # Col O - Desfase (si tiene valor → advertencia)
        {"canonical": "COL_EXTRA", "aliases": ["COLUMNA EXTRA", "DESFASE"]},
        # Otros opcionales (no en encabezado oficial)
        {"canonical": "POSICION", "aliases": ["CARGO", "PUESTO"]},
        {"canonical": "EMPRESA", "aliases": ["COMPANY"]},
        {"canonical": "CONTACTO", "aliases": ["CONTACT"]},
    ],
}

inject_en_labels_into_template_columns(TEMPLATE_COLUMNS)

inject_max_char_hints_into_columns(
    TEMPLATE_COLUMNS.get("customs_brokers"), CUSTOMS_BROKERS_CSV_MAX_CHARS
)
for _col in TEMPLATE_COLUMNS.get("customs_brokers") or []:
    if _col.get("canonical") == "TIPO":
        merge_enum_hint_before_max(_col, ["MEX", "AME"])

# Orden oficial de columnas (para CSV sin encabezado o detección)
CUSTOMS_BROKERS_FIELDNAMES_ORDER = [
    "TIPO",
    "CLAVE",
    "LICENCIA",
    "NOMBRE",
    "RFC",
    "DIRECCION",
    "CODIGO POSTAL",
    "CIUDAD",
    "ESTADO",
    "PAIS",
    "TELEFONO",
    "FAX",
    "EMAIL",
    "PERSONAL_ID",
]

# Si la primera celda de la primera fila está en este set, se trata como CSV sin encabezado
CUSTOMS_BROKERS_HEADERLESS_FIRST_CELL = frozenset(
    {"MEX", "AME", "M", "A", "MEXICANO", "AMERICANO"}
)


def build_normalized_lookup(normalize_header_fn) -> Dict[str, str]:
    """normalized_header -> canonical_name para plantilla customs_brokers."""
    cols = TEMPLATE_COLUMNS.get("customs_brokers")
    if not cols:
        return {}
    lookup: Dict[str, str] = {}
    for item in cols:
        canonical = item["canonical"]
        lookup[normalize_header_fn(canonical)] = canonical
        for alias in item.get("aliases") or []:
            lookup[normalize_header_fn(alias)] = canonical
        merge_labels_into_lookup(item, canonical, normalize_header_fn, lookup)
        merge_download_header_into_lookup(item, canonical, normalize_header_fn, lookup)
    for idx, name in enumerate(CUSTOMS_BROKERS_FIELDNAMES_ORDER):
        lookup[normalize_header_fn(f"_COL_{idx}_")] = name
    return lookup


def row_from_template(row: Dict[str, Any], normalize_header_fn) -> Dict[str, Any]:
    """Fila CSV con solo columnas de la plantilla, en nombres canónicos."""
    lookup = build_normalized_lookup(normalize_header_fn)
    if not lookup:
        return {normalize_header_fn(k): cell_to_str(v) for k, v in row.items()}
    out: Dict[str, Any] = {}
    for csv_header, value in row.items():
        key_norm = normalize_header_fn(csv_header)
        if key_norm in lookup:
            out[lookup[key_norm]] = cell_to_str(value)
    return out
