"""Parameter suggestion arbitrator.

When multiple sources (Bayesian optimizer, strategy evolution, LLM advisor)
propose conflicting parameter changes, this module arbitrates according to
a data-driven priority:

    Bayesian (3) > Evolution (2) > Advisor (1)

Usage::

    from src.param_arbitrator import arbitrate

    suggestions = [
        {"source": "bayesian", "param": "sl_atr", "value": 1.8, "confidence": 0.85},
        {"source": "evolution", "param": "sl_atr", "value": 1.5, "confidence": 0.60},
    ]
    resolved = arbitrate(suggestions)
"""

from __future__ import annotations

from typing import Any, Dict, List

# ── priority table ───────────────────────────────────────────────

SOURCE_PRIORITY: Dict[str, int] = {
    "bayesian":  3,   # data-driven, highest trust
    "evolution": 2,   # statistics-driven from real trades
    "advisor":   1,   # LLM-driven, qualitative
}


def arbitrate(suggestions: List[Dict[str, Any]]) -> Dict[str, Any]:
    """Resolve conflicting parameter suggestions.

    Each suggestion should have::

        {"source": "bayesian|evolution|advisor",
         "param": "param_name",
         "value": <proposed_value>,
         "confidence": 0.0-1.0}

    Returns a dict keyed by param name with the winning suggestion.
    Conflicts where a lower-priority source has significantly higher
    confidence (≥0.1 margin) are flagged for human review.
    """
    result: Dict[str, Any] = {}

    # stable sort: highest priority first
    sorted_suggestions = sorted(
        suggestions,
        key=lambda s: SOURCE_PRIORITY.get(s.get("source", ""), 0),
        reverse=True,
    )

    for sug in sorted_suggestions:
        param = sug.get("param")
        if not param:
            continue
        if param not in result:
            result[param] = dict(sug)
        else:
            existing = result[param]
            # If challenger has substantially higher confidence, flag conflict
            existing_conf = float(existing.get("confidence", 0))
            challenger_conf = float(sug.get("confidence", 0))
            if challenger_conf > existing_conf + 0.10:
                result[param] = {
                    "value": existing["value"],
                    "source": f"CONFLICT:{existing['source']}vs{sug['source']}",
                    "confidence": existing["confidence"],
                    "conflict_details": {
                        "winner": existing,
                        "challenger": sug,
                    },
                }

    return result
