"""Identity transform cascade for pre-match data prep."""
from __future__ import annotations

print("[IDENTITY_TRANSFORMS DEBUG] Starting imports...")

import logging
import time
from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple

import pandas as pd

print("[IDENTITY_TRANSFORMS DEBUG] Importing domain_autoclean...")
from .domain_autoclean import (
    auto_clean_domains,
    AUTO_B2C_COL,
    AUTO_DOMAIN_FOR_BLOCKING_COL,
    AUTO_NEEDS_COMPANY_LOOKUP_COL,
)
print("[IDENTITY_TRANSFORMS DEBUG] Importing company_to_domain...")
from ..operators.company_to_domain import company_to_domain
print("[IDENTITY_TRANSFORMS DEBUG] Importing identity_profiles...")
from .identity_profiles import DNSCircuitBreaker
print("[IDENTITY_TRANSFORMS DEBUG] Importing domain_family...")
from ..services.domain_family import get_registry
print("[IDENTITY_TRANSFORMS DEBUG] Importing utils_normalize...")
from fmatch.utils_normalize import strip_formerly_known_as
print("[IDENTITY_TRANSFORMS DEBUG] All imports complete!")

log = logging.getLogger(__name__)

TRANSFORM_COMPANY_CANONICAL_COL = "__transform_company_canonical"
TRANSFORM_IDENTITY_READY_COL = "__transform_identity_ready"
TRANSFORM_IDENTITY_STATUS_COL = "__transform_identity_status"
_TRANSFORM_METRICS_ATTR = "_identity_transform_metrics"

_IDENTITY_STATUS_READY = "ready"
_IDENTITY_STATUS_NEEDS_COMPANY = "missing_company"
_IDENTITY_STATUS_NO_DOMAIN = "no_domain"

_NO_DOMAIN_SENTINELS = {"", "__no_domain__", "__auto_no_domain__"}
_COMPANY_TOKENS = (
    "company",
    "account",
    "organization",
    "organisation",
    "business",
    "employer",
    "firm",
    "corp",
    "corporation",
    "enterprise",
)
_COMPANY_CONFIDENCE_MIN = 0.80


def run_identity_transforms(
    df: pd.DataFrame,
    *,
    dataset: str = "source",
    domain_hints: Optional[Sequence[str]] = None,
    company_hints: Optional[Sequence[str]] = None,
    email_hints: Optional[Sequence[str]] = None,
    website_hints: Optional[Sequence[str]] = None,
    enabled: bool = True,
    options: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
    """Run Foundry identity transforms (normalize -> backfill domains -> backfill companies)."""

    if df is None:
        return {}

    transforms_enabled = bool(enabled)
    options = options or {}
    profile_name = options.get("profile")
    company_options = dict(options.get("company_to_domain", {}))
    circuit_config = options.get("circuit_breaker", {})
    if options.get("transforms_enabled") is not None:
        transforms_enabled = transforms_enabled and bool(
            options.get("transforms_enabled")
        )
    initial_dns_enabled = bool(company_options.get("use_dns", False))

    # Timing instrumentation
    t_start = time.time()
    metrics = dict(
        auto_clean_domains(
            df,
            dataset=dataset,
            domain_hints=domain_hints,
            email_hints=email_hints,
            website_hints=website_hints,
        )
    )
    t_autoclean = time.time() - t_start
    metrics["transform_profile"] = profile_name
    metrics["initial_dns_requested"] = initial_dns_enabled

    row_count = int(metrics.get("row_count", len(df)))
    dataset_key = (dataset or "source").strip().lower()
    log_prefix = f"[IDENTITY:{dataset_key.upper()}]"

    if row_count == 0:
        summary = {
            "enabled": transforms_enabled,
            "dataset": dataset_key,
            "rows": row_count,
            "estimated_credits": row_count if transforms_enabled else 0,
            "identity_ready_rows": 0,
            "identity_ready_pct": 0.0,
            "identity_missing_rows": 0,
            "identity_missing_company_rows": 0,
            "identity_no_domain_rows": 0,
            "domain_backfilled": 0,
            "company_backfilled": 0,
            "profile": profile_name,
        }
        metrics["transforms"] = summary
        df.attrs["_auto_clean_metrics"] = dict(metrics)
        df.attrs[_TRANSFORM_METRICS_ATTR] = summary
        return metrics

    if not transforms_enabled:
        log.info("%s Identity transforms disabled by configuration", log_prefix)
        metrics["transform_domain_candidates"] = 0
        metrics["transform_domain_attempted"] = 0
        metrics["transform_domain_backfilled"] = 0
        metrics["transform_b2c_replaced"] = 0
        metrics["transform_company_candidates"] = 0
        metrics["transform_company_backfilled"] = 0
        metrics["identity_ready_rows"] = 0
        metrics["identity_ready_pct"] = 0.0
        metrics["identity_missing_rows"] = row_count
        metrics["identity_missing_company_rows"] = row_count
        metrics["identity_no_domain_rows"] = row_count

        summary = {
            "enabled": False,
            "dataset": dataset_key,
            "rows": row_count,
            "estimated_credits": 0,
            "identity_ready_rows": 0,
            "profile": profile_name,
            "dns_requested": initial_dns_enabled,
            "identity_ready_pct": 0.0,
            "identity_missing_rows": row_count,
            "identity_missing_company_rows": row_count,
            "identity_no_domain_rows": row_count,
            "domain_backfilled": 0,
            "company_backfilled": 0,
            "message": "Identity transforms skipped (user opt-out).",
        }
        metrics["transforms"] = summary
        df.attrs["_auto_clean_metrics"] = dict(metrics)
        df.attrs[_TRANSFORM_METRICS_ATTR] = summary
        return metrics

    log.info(f"{log_prefix} [DEBUG] Columns before domain check: {df.columns.tolist()}")
    log.info(
        f"{log_prefix} [DEBUG] AUTO_DOMAIN_FOR_BLOCKING_COL = '{AUTO_DOMAIN_FOR_BLOCKING_COL}'"
    )
    log.info(
        f"{log_prefix} [DEBUG] Column exists: {AUTO_DOMAIN_FOR_BLOCKING_COL in df.columns}"
    )

    if AUTO_DOMAIN_FOR_BLOCKING_COL not in df.columns:
        log.info(
            f"{log_prefix} [DEBUG] Creating missing column '{AUTO_DOMAIN_FOR_BLOCKING_COL}'"
        )
        df[AUTO_DOMAIN_FOR_BLOCKING_COL] = pd.Series(
            pd.NA, index=df.index, dtype=object
        )
    else:
        log.info(
            f"{log_prefix} [DEBUG] Column '{AUTO_DOMAIN_FOR_BLOCKING_COL}' already exists"
        )

    log.info(f"{log_prefix} [DEBUG] Columns after domain check: {df.columns.tolist()}")
    domain_series = df[AUTO_DOMAIN_FOR_BLOCKING_COL].astype(object)
    domain_values = domain_series.fillna("").astype(str).str.strip()

    needs_lookup_mask = _boolean_series(df, AUTO_NEEDS_COMPANY_LOOKUP_COL)
    b2c_mask = (
        _boolean_series(df, AUTO_B2C_COL)
        if dataset_key == "source"
        else pd.Series(False, index=df.index, dtype=bool)
    )

    needs_domain_mask = domain_values.isin(_NO_DOMAIN_SENTINELS) | needs_lookup_mask
    if dataset_key == "source":
        needs_domain_mask = needs_domain_mask | b2c_mask

    company_columns = _discover_company_columns(df, company_hints)
    company_series = _coalesce_company_values(df, company_columns)
    prepared_company = company_series.map(_normalize_company_value)
    company_available_mask = prepared_company.str.len() > 0

    domain_candidate_mask = needs_domain_mask & company_available_mask
    domain_candidates = int(domain_candidate_mask.sum())

    if domain_candidates:
        log.info(
            "%s Domain backfill candidates: %d (total flagged: %d)",
            log_prefix,
            domain_candidates,
            int(needs_domain_mask.sum()),
        )
    else:
        log.info(
            "%s No domain backfill candidates (flagged rows: %d)",
            log_prefix,
            int(needs_domain_mask.sum()),
        )

    enriched_domains = 0
    b2c_replaced = 0
    lookup_cache: Dict[str, Optional[Dict[str, Any]]] = {}
    t_lookup_elapsed = 0.0

    if domain_candidates:
        # Phase 1: Collect unique company names and batch lookup (vectorized optimization)
        t_lookup_start = time.time()
        unique_companies = prepared_company[domain_candidate_mask].dropna().unique()
        unique_count = len(unique_companies)
        duplicate_savings = domain_candidates - unique_count
        log.info(
            "%s Batch lookup: %d unique companies (from %d candidates, saved %d duplicate lookups = %.1f%% reduction)",
            log_prefix,
            unique_count,
            domain_candidates,
            duplicate_savings,
            (duplicate_savings / domain_candidates * 100) if domain_candidates else 0,
        )

        dns_circuit: Optional[DNSCircuitBreaker] = None
        if company_options.get("use_dns"):
            try:
                dns_circuit = DNSCircuitBreaker(
                    threshold=float(circuit_config.get("threshold", 0.3)),
                    sample_size=int(circuit_config.get("sample_size", 50)),
                )
            except Exception:
                dns_circuit = DNSCircuitBreaker()

        try:
            max_candidates_opt = int(company_options.get("max_candidates", 5))
            if max_candidates_opt < 1:
                max_candidates_opt = 1
        except (TypeError, ValueError):
            max_candidates_opt = 5
        company_options["max_candidates"] = max_candidates_opt

        try:
            dns_timeout_opt = float(company_options.get("dns_timeout", 2.0))
            if dns_timeout_opt <= 0:
                dns_timeout_opt = 0.1
        except (TypeError, ValueError):
            dns_timeout_opt = 2.0
        company_options["dns_timeout"] = dns_timeout_opt
        company_options["use_registry"] = bool(
            company_options.get("use_registry", True)
        )

        # Diagnostic tracking for specific companies (case-insensitive, normalized cache keys)
        # Use [IDTRACE] prefix for easy log filtering
        diagnostic_companies = {
            "amazon",
            "oracle",
            "ibm",
            "lloyds banking group",
            "lloyds bank",  # Lloyds variations
            "gdit",
            "general dynamics information technology (gdit)",  # GDIT variations
        }

        for company_name in unique_companies:
            if not company_name:
                continue
            cache_key = company_name.lower()

            is_diagnostic = cache_key in diagnostic_companies

            try:
                use_dns = bool(company_options.get("use_dns", False))
                if dns_circuit and dns_circuit.is_open:
                    use_dns = False
                lookup_cache[cache_key] = company_to_domain(
                    company_name,
                    use_registry=bool(company_options.get("use_registry", True)),
                    use_dns=use_dns,
                    max_candidates=company_options.get("max_candidates", 5),
                    dns_timeout=company_options.get("dns_timeout", 2.0),
                )

                if is_diagnostic:
                    result = lookup_cache[cache_key]
                    value = result.get("value") if isinstance(result, dict) else None
                    domain = value.get("domain") if isinstance(value, dict) else None
                    conf = value.get("confidence") if isinstance(value, dict) else None
                    source = value.get("source") if isinstance(value, dict) else None
                    log.info(
                        "%s [IDTRACE] Lookup for '%s' (key='%s'): domain=%s, conf=%s, source=%s",
                        log_prefix,
                        company_name,
                        cache_key,
                        domain,
                        conf,
                        source,
                    )

                if dns_circuit and company_options.get("use_dns"):
                    value = lookup_cache[cache_key] or {}
                    payload_value = (
                        value.get("value") if isinstance(value, dict) else {}
                    )
                    dns_success = (
                        isinstance(payload_value, dict)
                        and payload_value.get("source") == "dns_validated"
                    )
                    dns_circuit.record(dns_success)
                    if dns_circuit.is_open:
                        company_options["use_dns"] = False
                        log.warning(
                            "%s DNS circuit breaker opened after %d/%d failures",
                            log_prefix,
                            dns_circuit.failures,
                            dns_circuit.attempts,
                        )
            except Exception as exc:  # pragma: no cover - defensive logging
                log.debug(
                    "%s company_to_domain failed for '%s': %s",
                    log_prefix,
                    company_name,
                    exc,
                )
                lookup_cache[cache_key] = None
                if is_diagnostic:
                    log.info(
                        "%s [IDTRACE] Lookup FAILED for '%s': %s",
                        log_prefix,
                        company_name,
                        exc,
                    )

        if dns_circuit:
            metrics["dns_circuit_breaker"] = dns_circuit.to_dict()
            metrics["dns_circuit_triggered"] = dns_circuit.is_open

        # Phase 2: Apply cached results to matching rows
        diagnostic_cache_keys = {
            "amazon",
            "oracle",
            "ibm",
            "lloyds banking group",
            "lloyds bank",
            "gdit",
            "general dynamics information technology (gdit)",
        }
        diagnostic_hits = {}

        for idx in df.index[domain_candidate_mask]:
            company_name = prepared_company.loc[idx]
            if not company_name:
                continue

            cache_key = company_name.lower()
            is_diagnostic = cache_key in diagnostic_cache_keys

            payload = lookup_cache.get(cache_key) or {}
            value = payload.get("value") if isinstance(payload, dict) else None
            domain = value.get("domain") if isinstance(value, dict) else None
            confidence = (
                value.get("confidence", "unknown")
                if isinstance(value, dict)
                else "unknown"
            )

            if is_diagnostic:
                if cache_key not in diagnostic_hits:
                    diagnostic_hits[cache_key] = []
                diagnostic_hits[cache_key].append(
                    {
                        "idx": idx,
                        "company_name": company_name,
                        "cache_hit": cache_key in lookup_cache,
                        "has_payload": bool(payload),
                        "has_value": bool(value),
                        "domain": domain,
                        "confidence": confidence,
                        "passes_domain_check": bool(domain),
                        "passes_conf_check": str(confidence).lower()
                        in {"high", "very_high"},
                    }
                )

            if not domain:
                if is_diagnostic:
                    log.info(
                        "%s [IDTRACE] Skipped '%s' (idx=%s): no domain in result",
                        log_prefix,
                        company_name,
                        idx,
                    )
                continue
            if str(confidence).lower() not in {"high", "very_high"}:
                if is_diagnostic:
                    log.info(
                        "%s [IDTRACE] Skipped '%s' (idx=%s): confidence=%s not in {high,very_high}",
                        log_prefix,
                        company_name,
                        idx,
                        confidence,
                    )
                continue

            domain_clean = domain.strip().lower()
            if not domain_clean:
                if is_diagnostic:
                    log.info(
                        "%s [IDTRACE] Skipped '%s' (idx=%s): domain empty after clean",
                        log_prefix,
                        company_name,
                        idx,
                    )
                continue

            df.at[idx, AUTO_DOMAIN_FOR_BLOCKING_COL] = domain_clean
            enriched_domains += 1

            if is_diagnostic:
                log.info(
                    "%s [IDTRACE] SUCCESS enriched '%s' (idx=%s) with domain=%s",
                    log_prefix,
                    company_name,
                    idx,
                    domain_clean,
                )

            if AUTO_NEEDS_COMPANY_LOOKUP_COL in df.columns:
                df.at[idx, AUTO_NEEDS_COMPANY_LOOKUP_COL] = False

            if dataset_key == "source" and AUTO_B2C_COL in df.columns:
                if bool(b2c_mask.loc[idx]):
                    b2c_replaced += 1
                df.at[idx, AUTO_B2C_COL] = False

        # Log summary of diagnostic companies
        for key, hits in diagnostic_hits.items():
            enriched_count = sum(
                1 for h in hits if h["passes_domain_check"] and h["passes_conf_check"]
            )
            log.info(
                "%s [IDTRACE] Summary '%s': %d candidate rows, %d enriched",
                log_prefix,
                key,
                len(hits),
                enriched_count,
            )

        t_lookup_elapsed = time.time() - t_lookup_start
        log.info(
            "%s Domain lookup phase complete: %d domains enriched in %.2fs (%.0fms per unique company)",
            log_prefix,
            enriched_domains,
            t_lookup_elapsed,
            (t_lookup_elapsed / unique_count * 1000) if unique_count else 0,
        )

    domain_values_after = (
        df[AUTO_DOMAIN_FOR_BLOCKING_COL].fillna("").astype(str).str.strip()
    )
    domain_present_mask = ~domain_values_after.isin(_NO_DOMAIN_SENTINELS)

    fill_before = int(metrics.get("domain_fill_before", 0))
    fill_after = int(domain_present_mask.sum())
    metrics["domain_fill_after"] = fill_after
    metrics["domain_coverage_after_pct"] = (
        (fill_after / row_count * 100.0) if row_count else 0.0
    )
    metrics["domain_fill_delta"] = fill_after - fill_before
    metrics["transform_domain_candidates"] = int(needs_domain_mask.sum())
    metrics["transform_domain_attempted"] = domain_candidates
    metrics["transform_domain_backfilled"] = enriched_domains
    metrics["transform_b2c_replaced"] = b2c_replaced
    metrics["needs_company_to_domain_remaining"] = int(
        (needs_domain_mask & ~domain_present_mask).sum()
    )

    company_augmented_cols = list(company_columns)
    if TRANSFORM_COMPANY_CANONICAL_COL in df.columns:
        company_augmented_cols.append(TRANSFORM_COMPANY_CANONICAL_COL)

    combined_company_series = _coalesce_company_values(df, company_augmented_cols)
    combined_company_mask = (
        combined_company_series.map(_normalize_company_value).str.len() > 0
    )

    company_candidate_mask = domain_present_mask & ~combined_company_mask
    company_candidates = int(company_candidate_mask.sum())

    backfilled_companies = 0
    registry_summary: Dict[str, Any] = {
        "source": "registry",
        "candidates": company_candidates,
    }

    if company_candidates:
        try:
            registry = get_registry()
        except Exception as exc:  # pragma: no cover - defensive logging
            log.warning("%s Domain registry unavailable: %s", log_prefix, exc)
            registry = None

        if registry is not None:
            if TRANSFORM_COMPANY_CANONICAL_COL not in df.columns:
                df[TRANSFORM_COMPANY_CANONICAL_COL] = pd.Series(
                    pd.NA, index=df.index, dtype=object
                )

            domain_cache: Dict[str, Optional[str]] = {}
            for idx in df.index[company_candidate_mask]:
                domain_value = domain_values_after.loc[idx]
                if not domain_value or domain_value in _NO_DOMAIN_SENTINELS:
                    continue

                if domain_value not in domain_cache:
                    family_id, confidence = _lookup_family_by_domain(
                        registry, domain_value
                    )
                    safe_name = None
                    if family_id and confidence >= _COMPANY_CONFIDENCE_MIN:
                        display_name = (
                            registry.get_display_name(family_id)
                            if hasattr(registry, "get_display_name")
                            else None
                        )
                        if display_name:
                            normalized = (
                                strip_formerly_known_as(display_name) or display_name
                            )
                            safe_name = normalized.strip()
                    domain_cache[domain_value] = safe_name
                safe_name = domain_cache.get(domain_value)
                if not safe_name:
                    continue

                df.at[idx, TRANSFORM_COMPANY_CANONICAL_COL] = safe_name
                if company_columns:
                    primary_col = company_columns[0]
                    if primary_col in df.columns:
                        current_value = _normalize_company_value(
                            df.at[idx, primary_col]
                        )
                        if not current_value:
                            df.at[idx, primary_col] = safe_name
                backfilled_companies += 1

            registry_summary["backfilled"] = backfilled_companies
        else:
            registry_summary["backfilled"] = 0
    else:
        registry_summary["backfilled"] = 0

    refreshed_company_cols = list(company_columns)
    if (
        TRANSFORM_COMPANY_CANONICAL_COL in df.columns
        and TRANSFORM_COMPANY_CANONICAL_COL not in refreshed_company_cols
    ):
        refreshed_company_cols.append(TRANSFORM_COMPANY_CANONICAL_COL)

    identity_company_series = _coalesce_company_values(df, refreshed_company_cols)
    identity_company_mask = (
        identity_company_series.map(_normalize_company_value).str.len() > 0
    )

    identity_ready_mask = domain_present_mask & identity_company_mask
    identity_status = pd.Series(
        _IDENTITY_STATUS_NO_DOMAIN, index=df.index, dtype=object
    )
    identity_status.loc[domain_present_mask] = _IDENTITY_STATUS_NEEDS_COMPANY
    identity_status.loc[identity_ready_mask] = _IDENTITY_STATUS_READY

    df[TRANSFORM_IDENTITY_READY_COL] = identity_ready_mask.astype(bool)
    df[TRANSFORM_IDENTITY_STATUS_COL] = identity_status

    identity_ready_rows = int(identity_ready_mask.sum())
    identity_no_domain_rows = int((~domain_present_mask).sum())
    identity_missing_company_rows = int(
        (domain_present_mask & ~identity_company_mask).sum()
    )

    metrics["transform_company_candidates"] = company_candidates
    metrics["transform_company_backfilled"] = backfilled_companies
    metrics["identity_ready_rows"] = identity_ready_rows
    metrics["identity_ready_pct"] = (
        (identity_ready_rows / row_count * 100.0) if row_count else 0.0
    )
    metrics["identity_missing_rows"] = row_count - identity_ready_rows
    metrics["identity_missing_company_rows"] = identity_missing_company_rows
    metrics["identity_no_domain_rows"] = identity_no_domain_rows

    transform_summary = {
        "enabled": True,
        "dataset": dataset_key,
        "rows": row_count,
        "estimated_credits": row_count,
        "domain_candidates": metrics["transform_domain_candidates"],
        "domain_attempted": metrics["transform_domain_attempted"],
        "domain_backfilled": metrics["transform_domain_backfilled"],
        "b2c_replaced": metrics["transform_b2c_replaced"],
        "company_candidates": metrics["transform_company_candidates"],
        "company_backfilled": metrics["transform_company_backfilled"],
        "identity_ready_rows": identity_ready_rows,
        "identity_missing_company_rows": identity_missing_company_rows,
        "identity_no_domain_rows": identity_no_domain_rows,
        "identity_ready_pct": metrics["identity_ready_pct"],
        "profile": profile_name,
        "dns_requested": initial_dns_enabled,
        "dns_final_enabled": bool(company_options.get("use_dns", False)),
        "dns_circuit_breaker": metrics.get("dns_circuit_breaker"),
    }
    transform_summary.update(registry_summary)

    df.attrs["_auto_clean_metrics"] = dict(metrics)
    df.attrs[_TRANSFORM_METRICS_ATTR] = transform_summary
    metrics["transforms"] = transform_summary

    # Log overall timing
    t_total = time.time() - t_start
    log.info(
        "%s Identity transforms complete in %.2fs (autoclean: %.2fs, lookups: %.2fs, rows: %d, ready: %d/%.1f%%)",
        log_prefix,
        t_total,
        t_autoclean,
        t_lookup_elapsed if domain_candidates else 0.0,
        row_count,
        identity_ready_rows,
        (identity_ready_rows / row_count * 100) if row_count else 0,
    )

    return metrics


def _discover_company_columns(
    df: pd.DataFrame, hints: Optional[Sequence[str]] = None
) -> List[str]:
    """Detect company columns using hints first, then fuzzy token match."""
    columns: List[str] = []
    if hints:
        for hint in hints:
            if isinstance(hint, str) and hint in df.columns and hint not in columns:
                columns.append(hint)
    for col in df.columns:
        if not isinstance(col, str) or col in columns:
            continue
        lowered = col.lower()
        if lowered.startswith("__auto_"):
            continue
        if any(token in lowered for token in _COMPANY_TOKENS):
            columns.append(col)
    return columns


def _coalesce_company_values(
    df: pd.DataFrame, columns: Optional[Iterable[str]]
) -> pd.Series:
    if not columns:
        return pd.Series([None] * len(df), index=df.index, dtype=object)
    result = pd.Series([None] * len(df), index=df.index, dtype=object)
    for col in columns:
        if col not in df.columns:
            continue
        series = df[col].astype(object)
        result = result.combine_first(series)
    return result


def _boolean_series(df: pd.DataFrame, column: str) -> pd.Series:
    if column in df.columns:
        return df[column].fillna(False).astype(bool)
    return pd.Series(False, index=df.index, dtype=bool)


def _normalize_company_value(value: Any) -> str:
    if value is None:
        return ""
    if isinstance(value, float) and pd.isna(value):
        return ""
    text = str(value).strip()
    if not text:
        return ""
    normalized = strip_formerly_known_as(text) or text
    return normalized.strip()


def _lookup_family_by_domain(registry: Any, domain: str) -> Tuple[Optional[str], float]:
    lookup = getattr(registry, "lookup_family_by_domain", None)
    if lookup is None:
        return (None, 0.0)
    try:
        result = lookup(domain)
    except Exception as exc:  # pragma: no cover - defensive logging
        log.debug("Domain registry lookup failed for %s: %s", domain, exc)
        return (None, 0.0)
    if isinstance(result, tuple):
        if len(result) == 2:
            family_id, confidence = result
            return family_id, float(confidence or 0.0)
        if result:
            family_id = result[0]
            confidence = result[1] if len(result) > 1 else 1.0
            return family_id, float(confidence or 0.0)
    return result, 1.0 if result else 0.0
