"""Utilidades puras reutilizadas por los casos de uso batch."""

from __future__ import annotations

from datetime import datetime, tzinfo
from typing import Iterable
import re


def slugify(value: str) -> str:
    """Normaliza un texto corto para usarlo como segmento legible de clave."""

    normalized = str(value or "").strip().lower()
    normalized = re.sub(r"[^a-z0-9áéíóúñ]+", "-", normalized)
    return normalized.strip("-")


def build_associated_user(patient_id: str, patient_name: str) -> str:
    """Prioriza la identificación del paciente y usa el nombre como respaldo."""

    if patient_id:
        return str(patient_id).strip()
    return re.sub(r"\s+", " ", str(patient_name or "").strip())


def build_case_key(
    *,
    patient_id: str,
    case_number: str,
    patient_name: str,
    fallback_name: str,
) -> str:
    """Construye un identificador estable del caso con los datos más confiables."""

    parts = [
        slugify(patient_id),
        slugify(case_number),
        slugify(patient_name),
    ]
    normalized_parts = [part for part in parts if part]
    return "-".join(normalized_parts[:3]) or slugify(fallback_name or "archivo")


def now_iso(colombia_tz: tzinfo) -> str:
    """Entrega un timestamp ISO en la zona horaria configurada."""

    return datetime.now(colombia_tz).isoformat()


def normalize_case_key_list(items: Iterable[object] | None) -> list[str]:
    """Elimina claves vacías o repetidas preservando el orden de llegada."""

    normalized: list[str] = []
    seen: set[str] = set()
    for raw in items or []:
        value = str(raw or "").strip()
        if not value or value in seen:
            continue
        normalized.append(value)
        seen.add(value)
    return normalized
