"""
Normaliza valores de negocio hacia el JSON del servicio DODA externo.
Solo cadenas limpias: sin mezclar claves de catálogo (broker_key, vehicle_key) como
sustituto de patente, CAAT o id de transporte cuando deban ser otros datos.
"""
from __future__ import annotations

import re
from typing import Any, Dict, Optional

# Aduana-Patente-Pedimento (3 segmentos; patente 4, pedimento alfanum limpio a dígitos)
_PEDIMENTO_DOC_SPLIT = re.compile(r"^[\s\-–—]*([^\s\-–—]+)[\s\-–—]+([^\s\-–—]+)[\s\-–—]+([^\s\-–—]+)[\s\-–—]*$")


def _digits_only(s: str, max_len: int) -> str:
    d = re.sub(r"\D", "", s or "")
    if max_len and len(d) > max_len:
        return d[-max_len:]
    return d


def normalize_aduana_despacho(value: Optional[str]) -> str:
    s = (value or "").strip()
    if not s:
        return ""
    return _digits_only(s, 3).zfill(3) if _digits_only(s, 3) else s[:3]


def normalize_aduana_seccion(value: Optional[str]) -> str:
    s = (value or "").strip()
    if not s:
        return ""
    d = _digits_only(s, 3)
    if d:
        return d.zfill(3)
    return s[:3]


def normalize_patente(value: Optional[str]) -> str:
    s = (re.sub(r"[\s\u00A0]+", " ", (value or "").strip()))
    d = re.sub(r"\D", "", s)
    if len(d) >= 4:
        return d[-4:]
    return s[:4] if s else ""


def normalize_caat(value: Optional[str]) -> str:
    return (value or "").strip()[:20]


def normalize_id_transporte(value: Optional[str]) -> str:
    return (re.sub(r"\s+", " ", (value or "").strip()))[:20]


def normalize_tipo_operacion(value: Optional[str]) -> str:
    v = (value or "").strip().upper()[:1]
    return v if v in ("I", "E") else v


def normalize_numero_gafete(value: Optional[str]) -> str:
    return (value or "").strip()[:250]


def normalize_fast_id(value: Optional[str]) -> str:
    return (value or "").strip()[:20]


def _parse_document_pedimento(
    document: Optional[str], authorization_patent: Optional[str]
) -> tuple[str, str]:
    """
    Retorna (patente_4, número_pedimento) a partir de documento o patente de autorización.
    """
    doc = (document or "").strip()
    m = _PEDIMENTO_DOC_SPLIT.match(doc)
    if m:
        b, c = m.group(2), m.group(3)
        pat = re.sub(r"\D", "", b)
        if len(pat) > 4:
            pat = pat[-4:]
        else:
            pat = pat.zfill(4) if pat else ""
        if not pat:
            ap = (authorization_patent or "").strip()
            pat = re.sub(r"\D", "", ap)[-4:].zfill(4) if ap else ""
        ped = re.sub(r"[^\d\w]", "", c) or re.sub(r"\D", "", c)
        return (pat[:4], ped)
    ped = re.sub(r"[^\d]", "", doc) if doc else ""
    ap = (authorization_patent or "").strip()
    pat4 = re.sub(r"\D", "", ap)[:4] if ap else ""
    if len(pat4) < 4 and ap and ap.isalnum():
        pat4 = (re.sub(r"\D", "", ap) + "0000")[:4] if re.sub(r"\D", "", ap) else (ap + "0")[:4]
    return (pat4, ped)


def normalize_doda_pedimento_row(
    document: Optional[str],
    authorization_patent: Optional[str],
    shipment: Optional[str],
    cove: Optional[str],
    umc: Optional[str],
    dta_niu: Optional[str],
    pedimento_type: Optional[str],
    effective: Any,
    diff: Any,
) -> Dict[str, Any]:
    ap_raw = (authorization_patent or "").strip()
    pat, ped = _parse_document_pedimento(document, ap_raw)
    if not pat and ap_raw:
        d = re.sub(r"\D", "", ap_raw)
        pat = d[-4:].zfill(4) if d else ap_raw[:4]

    rem = (shipment or "").strip()[:11] if (shipment or "").strip() else ""
    if not rem and ped:
        rem = ped

    return {
        "patente": pat,
        "pedimento": ped,
        "numero_remesa": rem,
        "tipo_pedimento": (pedimento_type or "")[:20],
        "dta_niu": (dta_niu or "")[:20],
        "importe_efectivo_dolares": float(effective or 0) if effective is not None else 0.0,
        "importe_diferencia_dolares": float(diff or 0) if diff is not None else 0.0,
        "campo_12_apendice_17": 0,
        "cove": (cove or "")[:50],
        "umc": (umc or "")[:20],
    }
