"""Compatibility adapter for legacy receipt payload fields.

This module provides a conservative `normalize_legacy_fields` function
that maps common legacy field names to the current canonical names.

The goal is to make canonicalization stable across payloads emitted
by older writers without making destructive or lossy transformations.
"""
from __future__ import annotations

from typing import Any, Dict
from receipts.compat.pyd import strip_signatures


def normalize_legacy_fields(payload: Any) -> Any:
    """Return a normalized copy of payload with legacy field aliases fixed.

    - If `payload` is not a dict, returns it unchanged.
    - Operates on a shallow copy; nested blocks that require special
      handling are conservatively adjusted where obvious.
    """
    if not isinstance(payload, dict):
        return payload

    out: Dict[str, Any] = dict(payload)

    # Simple one-to-one key renames
    renames = {
        "game_id": "asset_id",
        "prediction_target": "target_name",
        "prediction_value": "pred_prob",
        "outcome_value": "realized_value",
        "prophecy_id": "parent_prophecy_id",
        "ci_lower": "ci90_lo",
        "ci_upper": "ci90_hi",
        "refusal_reasons": "reasons",
        "gates_failed": "failed_facets",
    }

    for old, new in renames.items():
        if old in out and new not in out:
            out[new] = out.pop(old)

    # Move 'witnesses' into metrics.witnesses when metrics absent/empty
    if "witnesses" in out:
        witnesses = out.pop("witnesses")
        metrics = out.get("metrics")
        if not isinstance(metrics, dict):
            metrics = {}
            out["metrics"] = metrics
        if "witnesses" not in metrics:
            metrics["witnesses"] = witnesses

    # policy_witnesses -> policy_witness (take first element if list)
    if "policy_witnesses" in out and "policy_witness" not in out:
        val = out.pop("policy_witnesses")
        if isinstance(val, (list, tuple)) and val:
            out["policy_witness"] = val[0]
        else:
            out["policy_witness"] = val

    return out


def normalize_payload(payload: Any) -> Any:
    """
    Apply legacy-field normalization and ensure signature is present when only signatures exist.
    """
    normalized = normalize_legacy_fields(payload)
    if not isinstance(normalized, dict):
        return normalized
    # If signature missing but signatures present, copy the first entry to signature.
    if "signature" not in normalized or normalized.get("signature") in (None, {}):
        sigs = normalized.get("signatures")
        if isinstance(sigs, (list, tuple)) and sigs:
            normalized["signature"] = sigs[0]
    return normalized


def canonical_payload_for_hash(payload: Any) -> Any:
    """
    Prepare a payload for hashing by normalizing and stripping signature fields.
    """
    normalized = normalize_payload(payload)
    try:
        return strip_signatures(normalized)
    except Exception:
        if isinstance(normalized, dict):
            normalized.pop("signature", None)
            normalized.pop("signatures", None)
        return normalized


__all__ = ["normalize_legacy_fields", "normalize_payload", "canonical_payload_for_hash"]
