"""SDK evaluate() -- submit agent output for risk assessment."""

from __future__ import annotations

import dataclasses

import httpx

from coalex.config import CoalexConfig

# Known metric catalog (validated client-side)
KNOWN_METRICS = {
    "f1",
    "word_overlap",
    "bleu",
    "rouge_l",
    "semantic_similarity",
    "exact_match",
    "levenshtein",
    "contains",
}


@dataclasses.dataclass(frozen=True)
class EvaluationDecision:
    """Result of an evaluate() call."""

    status: str  # "auto_approved" | "escalated" | "rejected"
    risk_score: float  # 0.0-1.0
    escalation_id: str | None  # present when status == "escalated"


def evaluate(
    *,
    trace_id: str,
    input: dict,
    output: dict,
    metrics: dict[str, list[str]],
    _config: CoalexConfig | None = None,
    _api_key: str | None = None,
) -> EvaluationDecision:
    """Submit agent output for risk-based evaluation.

    Args:
        trace_id: Links to an observed trace.
        input: Agent input data.
        output: Agent output data.
        metrics: Map of output field names to metric function names.
        _config: Override config (testing only).
        _api_key: Override API key (testing only).
    """
    import coalex as _sdk

    cfg = _config or _sdk._config
    api_key = _api_key or _sdk._api_key
    if cfg is None:
        raise RuntimeError("coalex.register() must be called before evaluate()")

    # Validate metrics against known catalog
    for field, metric_list in metrics.items():
        unknown = set(metric_list) - KNOWN_METRICS
        if unknown:
            raise ValueError(f"Unknown metrics for field '{field}': {unknown}")

    payload = {
        "trace_id": trace_id,
        "input": input,
        "output": output,
        "metrics": metrics,
    }

    with httpx.Client(timeout=30.0) as client:
        resp = client.post(
            f"{cfg.endpoint}/api/v1/evaluate",
            json=payload,
            headers={"Authorization": f"Bearer {api_key}"},
        )
        resp.raise_for_status()

    data = resp.json()
    return EvaluationDecision(
        status=data["status"],
        risk_score=data["risk_score"],
        escalation_id=data.get("escalation_id"),
    )
