"""Combina atributos de multiples candidatos de la misma entidad."""

from __future__ import annotations

_NUMERIC_FIELDS = {"risk_score", "balance", "cvss"}
_DATE_MIN_FIELDS = {"first_seen", "created_date"}
_DATE_MAX_FIELDS = {"last_seen", "expires_date"}
_BOOL_FIELDS = {"verified", "exploited"}


def merge_entity_attributes(attr_list: list[dict]) -> dict:
    """Combina atributos de multiples candidatos de la misma entidad.

    Para cada campo presente en cualquier candidato recopila todos los valores
    non-null y aplica heuristicas de resolucion por tipo de campo:
    - Numerico (risk_score, balance, cvss): max
    - Fecha min (first_seen, created_date): min (mas antigua)
    - Fecha max (last_seen, expires_date): max (mas reciente)
    - Lista (cualquier valor de tipo list): union sin duplicados
    - Boolean (verified, exploited): OR logico
    - String: el mas largo

    Args:
        attr_list: Lista de dicts con los atributos de cada candidato.

    Returns:
        Dict con los atributos fusionados.
    """
    if not attr_list:
        return {}

    # Recopilar todas las claves presentes en cualquier candidato
    all_keys: set[str] = set()
    for attrs in attr_list:
        all_keys.update(attrs.keys())

    merged: dict = {}

    for key in all_keys:
        # Recopilar valores non-null
        values = [attrs[key] for attrs in attr_list if key in attrs and attrs[key] is not None]

        if not values:
            merged[key] = None
            continue

        if len(values) == 1:
            merged[key] = values[0]
            continue

        # Todos iguales
        if all(v == values[0] for v in values):
            merged[key] = values[0]
            continue

        # Resolver conflicto segun tipo de campo
        if key in _NUMERIC_FIELDS:
            merged[key] = max(values)
        elif key in _DATE_MIN_FIELDS:
            merged[key] = min(values)
        elif key in _DATE_MAX_FIELDS:
            merged[key] = max(values)
        elif key in _BOOL_FIELDS:
            merged[key] = any(values)
        elif isinstance(values[0], list):
            # Union de listas sin duplicados, preservando orden de aparicion
            seen: list = []
            for lst in values:
                for item in lst:
                    if item not in seen:
                        seen.append(item)
            merged[key] = seen
        else:
            # String u otro: usar el mas largo
            str_values = [str(v) for v in values]
            merged[key] = max(str_values, key=len)

    return merged
