"""
Resolve American (US) tariff fraction codes against SITAR fracciones-usa.
Used by sync validators and CSV/layout enrichment (no asyncio.run).
"""

from __future__ import annotations

import re
from typing import List, Optional, Tuple

from .schemas import FraccionesUSAResponse
from .service import FraccionesUSAService


def normalize_american_fraction_code_candidates(raw_code: str) -> List[str]:
    """
    Map user input to candidate strings to query SITAR (dotted HTS vs digits-only).
    Mirrors logic in items imports/validators/common.py.
    """
    normalized_raw = (raw_code or "").strip()
    if not normalized_raw:
        return []

    digits_only = re.sub(r"[.\s\-]", "", normalized_raw)

    candidates: List[str] = []
    candidates.append(normalized_raw)

    if len(digits_only) == 10:
        candidates.append(
            f"{digits_only[:4]}.{digits_only[4:6]}.{digits_only[6:8]}.{digits_only[8:10]}"
        )
    elif len(digits_only) == 8:
        candidates.append(
            f"{digits_only[:4]}.{digits_only[4:6]}.{digits_only[6:8]}"
        )

    candidates.append(digits_only)

    seen: set[str] = set()
    deduped: List[str] = []
    for c in candidates:
        if not c or c in seen:
            continue
        seen.add(c)
        deduped.append(c)
    return deduped


def _digits(code: str) -> str:
    return re.sub(r"[.\s\-]", "", code or "")


def canonical_code_from_sitar_row(item: FraccionesUSAResponse) -> str:
    """Same precedence as USTariffFractionMapper.to_domain for stored line value."""
    return (
        (item.FRACCION_CON_PUNTO or item.FRACCION_MOSTRAR or item.FRACCION_SIN_PUNTO or "")
        .strip()
    )


def resolve_american_fraction_from_sitar(
    raw_code: str,
) -> Optional[Tuple[FraccionesUSAResponse, str]]:
    """
    Returns (SITAR row, canonical_code) if found, else None.
    canonical_code is suitable for persisting on line customs / exports.
    """
    if not (raw_code or "").strip():
        return None

    target_digits = _digits(raw_code)
    if not target_digits:
        return None

    candidates = normalize_american_fraction_code_candidates(raw_code)
    tried_searches: set[tuple[Optional[str], Optional[str]]] = set()

    for cand in candidates:
        clean = cand.replace(".", "").replace("-", "").replace(" ", "")
        if clean.isdigit() and len(clean) >= 4:
            search_frac, search_desc = cand, None
        else:
            search_frac, search_desc = None, cand

        key = (search_frac, search_desc)
        if key in tried_searches:
            continue
        tried_searches.add(key)

        rows = FraccionesUSAService.search_sync(
            fraccion=search_frac,
            descripcion=search_desc,
            skip=0,
            limit=100,
        )
        for row in rows:
            canon = canonical_code_from_sitar_row(row)
            if _digits(canon) == target_digits:
                return (row, canon)

    return None


MAX_AMERICAN_FRACTION_DB_LEN = 16


def store_canonical_american_code(canon: str) -> str:
    """Fit SITAR canonical HTS string into DB column (VARCHAR 16)."""
    s = (canon or "").strip()
    if len(s) <= MAX_AMERICAN_FRACTION_DB_LEN:
        return s
    digits = re.sub(r"[.\s\-]", "", s)
    return digits[:MAX_AMERICAN_FRACTION_DB_LEN]


def american_fraction_ad_valorem_from_row(item: FraccionesUSAResponse) -> Optional[float]:
    """Parse TARIFA1 like USTariffFractionMapper."""
    if not item.TARIFA1:
        return None
    try:
        return float(str(item.TARIFA1).replace("%", "").strip())
    except (ValueError, TypeError):
        return None
