"""Shared extraction normalization helpers for enrichment adapters."""

from __future__ import annotations

from typing import Any, Iterable, List, Optional


def clean_str(value: Any) -> Optional[str]:
    """Return trimmed string for scalar values; ignore nested objects."""
    if value is None:
        return None
    if isinstance(value, (dict, list, tuple, set)):
        return None
    text = str(value).strip()
    return text or None


def dedupe_strings(values: Iterable[Any]) -> List[str]:
    """Deduplicate string-like values case-insensitively preserving order."""
    deduped: List[str] = []
    seen = set()
    for item in values:
        text = clean_str(item)
        if not text:
            continue
        key = text.lower()
        if key in seen:
            continue
        seen.add(key)
        deduped.append(text)
    return deduped


def normalize_domain(value: Any) -> Optional[str]:
    """Normalize arbitrary domain/url-like input to lowercase bare domain."""
    text = clean_str(value)
    if not text:
        return None
    domain = text.lower()
    for prefix in ("http://", "https://"):
        if domain.startswith(prefix):
            domain = domain[len(prefix):]
            break
    if domain.startswith("www."):
        domain = domain[4:]
    domain = domain.split("/", 1)[0]
    domain = domain.split("?", 1)[0]
    domain = domain.split("#", 1)[0]
    domain = domain.strip()
    return domain or None


def coerce_int(value: Any) -> Optional[int]:
    """Best-effort integer coercion for provider payloads."""
    if value is None or value == "":
        return None
    if isinstance(value, bool):
        return None
    if isinstance(value, int):
        return value
    if isinstance(value, float):
        return int(value)
    text = clean_str(value)
    if not text:
        return None
    try:
        return int(float(text.replace(",", "")))
    except ValueError:
        return None


def join_location_parts(parts: Iterable[Any]) -> Optional[str]:
    """Join non-empty location parts into a display string."""
    labels = [text for part in parts if (text := clean_str(part))]
    return ", ".join(labels) if labels else None
