"""
Plantillas CSV para Exportación (encabezado y partidas).
Misma estructura que facturas exp_def_header / exp_def_details; módulo autocontenido.
"""

from typing import Dict, List, Any, Optional

from ..common.cell_value import cell_to_str
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 ..facturas.invoice_csv_column_hints import apply_invoice_csv_hints

# Columnas para encabezado y partidas de exportación (EstructuraEncFacExpoCamReg / EstructuraParExpoCamReg)
TEMPLATE_COLUMNS: Dict[str, List[Dict[str, Any]]] = {
    "exp_def_header": [
        {"canonical": "NUMERO FACTURA", "aliases": ["NUM FACTURA", "FACTURA", "ID"]},
        {"canonical": "FECHA FACTURA", "aliases": ["FECHA"]},
        {"canonical": "FECHA EMISION"},
        {"canonical": "CLAVE PROVEEDOR"},
        {"canonical": "CLAVE VENDIDO A"},
        {"canonical": "CLAVE ENVIADO A"},
        {"canonical": "REGIMEN", "aliases": ["CLAVEDOCUMENTO"]},
        {"canonical": "ADUANA DE CRUCE"},
        {"canonical": "CLAVE MONEDA"},
        {"canonical": "CLAVE INCOTERM"},
        {"canonical": "TIPO MONEDA"},
        {"canonical": "TIPO DE CAMBIO"},
        {"canonical": "TIPO PESO"},
        {"canonical": "TIPO TRANSPORTE"},
        {"canonical": "REMESA"},
        {"canonical": "AGENTE ADUANAL"},
        {"canonical": "FLETES"},
        {"canonical": "VALOR SEGUROS"},
        {"canonical": "SEGUROS"},
        {"canonical": "EMBALAJES"},
        {"canonical": "OTROS INCREMENTABLES"},
        {"canonical": "NUM PROYECTO", "aliases": ["NUMPROYECTO"]},
        {"canonical": "ORDEN COMPRA", "aliases": ["ORDENCOMPRA"]},
        {"canonical": "FACTURA ALTERNA"},
        {"canonical": "FACTURA EXPO REF", "aliases": ["FACTURAEXPOREF"]},
        {"canonical": "OBSERVACIONES E"},
        {"canonical": "OBSERVACIONES I"},
        {"canonical": "E DOCUMENT"},
        {"canonical": "NUM OPERACION"},
        {"canonical": "CLAVE TRANSPORTISTA"},
        {"canonical": "NOMBRE CONDUCTOR"},
        {"canonical": "NUMERO TRANSPORTE"},
        {"canonical": "PRECINTO"},
    ],
    "exp_def_details": [
        {"canonical": "NUMERO FACTURA", "aliases": ["NUM FACTURA", "FACTURA"]},
        {"canonical": "LINEA", "aliases": ["RENGLON", "PARTIDA"]},
        {"canonical": "NUMPARTE", "aliases": ["NUMERO PARTE"]},
        {"canonical": "PRECIO UNITARIO", "aliases": ["PRECIOUNITARIO"]},
        {"canonical": "VALOR COMERCIAL", "aliases": ["VALORCOMERCIAL"]},
        {"canonical": "CANTIDAD"},
        {"canonical": "CANTIDAD BULTOS", "aliases": ["CANTIDADBULTOS"]},
        {"canonical": "DESCRIPCION"},
        {"canonical": "PAIS ORIGEN", "aliases": ["PAISORIGEN"]},
        {"canonical": "FRACCION"},
        {"canonical": "ORDEN DE COMPRA", "aliases": ["ORDENCOMPRA"]},
    ],
    # Partidas exportación definitiva (Clarion EstructuraParExpoCamReg: A–V)
    "exp_def_partidas": [
        {"canonical": "NUMERO FACTURA EXPO", "aliases": ["NUMERO FACTURA EXPO.", "NUM FACTURA EXPO", "FACTURA EXPO"]},
        {"canonical": "LINEA EXPO", "aliases": ["LINEA EXPO.", "RENGLON EXPO"]},
        {"canonical": "TIPO DE IMPO", "aliases": ["TIPO DE IMPO.", "TIPO IMPO", "PROCEDENCIA"]},
        {"canonical": "FACTURA IMPO", "aliases": ["FACTURA IMPO.", "FACTURA IMPORTACION"]},
        {"canonical": "LINEA IMPO", "aliases": ["LINEA IMPO.", "LINEA IMPORTACION"]},
        {"canonical": "GENERA DESCARGA", "aliases": ["GENERA DESCARGA?", "DESCARGA"]},
        {"canonical": "CANTIDAD EXPORTADA/DESCARGAR", "aliases": ["CANTIDAD EXPORTADA", "CANTIDAD EXPORTADA/DESCARGAR", "CANTIDAD"]},
        {"canonical": "UNIDAD DE MEDIDA", "aliases": ["U.M.", "UNIDAD MEDIDA"]},
        {"canonical": "COSTO UNITARIO", "aliases": ["COSTOUNITARIO"]},
        {"canonical": "PESO NETO", "aliases": ["PESONETO"]},
        {"canonical": "PESO BRUTO", "aliases": ["PESOBRUTO"]},
        {"canonical": "SE PAGO IMPUESTO", "aliases": ["SE PAGO IMPUESTO? (SI o NO)", "SEPAGOIMPUESTO"]},
        {"canonical": "FORMA DE PAGO", "aliases": ["FORMADEPAGO", "FORMA PAGO"]},
        {"canonical": "DESCRIPCION EXTRA", "aliases": ["DESCRIPCION EXTRA", "DESCRIPCIONEXTRA"]},
        {"canonical": "INFORMACION ADICIONAL", "aliases": ["INFORMACION ADICIONAL", "INFORMACIONADICIONAL"]},
        {"canonical": "AGREGAR(A)/SUSTITUIR(S)", "aliases": ["AGREGAR(A)/SUSTITUIR(S)", "AGREGAR/SUSTITUIR", "SUSTITUIR"]},
        {"canonical": "LOTE"},
        {"canonical": "NUMERO ENTRADA", "aliases": ["NUMERO ENTRADA", "NUM ENTRADA"]},
        {"canonical": "ES PARTIDA/SUBPARTIDA", "aliases": ["ES PARTIDA/SUBPARTIDA", "ESSUBPARTIDA", "ES PARTIDA O SUBPARTIDA"]},
        {"canonical": "LINEA PRINCIPAL", "aliases": ["LINEAPRINCIPAL", "PARTIDA PRINCIPAL"]},
        {"canonical": "FRACCION AMERICANA", "aliases": ["FRACCION AMERICANA", "FRACCIONAMERICANA"]},
        {"canonical": "FRACCION ARANCELARIA", "aliases": ["FRACCION ARANCELARIA", "FRACCIONARANCELARIA"]},
        {"canonical": "CANTIDAD BULTOS", "aliases": ["CANTIDADBULTOS"]},
        {"canonical": "CLAVE BULTOS", "aliases": ["CLAVEBULTOS"]},
        {"canonical": "PAIS ORIGEN", "aliases": ["PAISORIGEN", "PAIS"]},
        {"canonical": "NUM. PARTE", "aliases": ["NUMPARTE", "NUMERO PARTE", "NUM PARTE"]},
        {"canonical": "ORDEN DE COMPRA", "aliases": ["ORDENCOMPRA", "ORDEN DE VENTA"]},
    ],
    # Series de exportación definitiva (misma estructura que imp_def_series; Clarion SERIES EXPO)
    "exp_def_series": [
        {"canonical": "NUMERO FACTURA", "aliases": ["NUM FACTURA", "FACTURA", "FACTURA EXPO"]},
        {"canonical": "LINEA FACTURA", "aliases": ["LINEA", "PARTIDA"]},
        {"canonical": "LINEA SERIE", "aliases": ["RENGLON", "LINEA SER"]},
        {"canonical": "SERIE", "aliases": ["NUMERO SERIE"]},
        {"canonical": "MODELO"},
        {"canonical": "NUM PARTE", "aliases": ["NUMPARTE", "NUMERO PARTE", "NUM PART"]},
        {"canonical": "SUB MODELO", "aliases": ["SUBMODELO", "SUB MODE"]},
        {"canonical": "NUMERO ID", "aliases": ["NUMEROID"]},
        {"canonical": "COL_EXTRA"},
    ],
}

inject_en_labels_into_template_columns(TEMPLATE_COLUMNS)

apply_invoice_csv_hints(TEMPLATE_COLUMNS)


def _resolve_template_columns(template_id: str) -> Optional[List[Dict[str, Any]]]:
    return TEMPLATE_COLUMNS.get(template_id)


def build_normalized_lookup(template_id: str, normalize_header_fn) -> Dict[str, str]:
    """normalized_header -> canonical_name."""
    cols = _resolve_template_columns(template_id)
    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)
    return lookup


def row_from_template(row: Dict[str, Any], template_id: str, normalize_header_fn) -> Dict[str, Any]:
    """Fila CSV -> dict con nombres canónicos de la plantilla."""
    lookup = build_normalized_lookup(template_id, 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
