"""把发布遥测状态转换为不含业务正文的运营告警。"""

from __future__ import annotations

from typing import Any


def build_release_alerts(
    *,
    status: str,
    rolled_back: bool,
    reasons: list[str] | tuple[str, ...],
    metrics: dict[str, Any],
) -> list[dict[str, str]]:
    alerts: list[dict[str, str]] = []
    reason_set = {str(item) for item in reasons}
    if bool(metrics.get("aggregation_failed")):
        alerts.append(
            _alert(
                "release_aggregation_failed",
                "error",
                "发布遥测聚合失败，候选版本已停止晋级。",
                "检查遥测存储和聚合作业；稳定版本会继续保护业务。",
            )
        )
    if rolled_back:
        alerts.append(
            _alert(
                "release_auto_rolled_back",
                "critical",
                "候选版本已因真实运行指标越界自动回滚。",
                "检查失败样本和版本差异后重新发布。",
            )
        )
    if int(metrics.get("runtime_failure_count") or 0) > 0:
        alerts.append(
            _alert(
                "runtime_failures_detected",
                "error",
                "候选规则出现结构化运行失败。",
                "优先修复 evaluator 或发布快照完整性。",
            )
        )
    if int(metrics.get("candidate_pending_label_count") or 0) > 0:
        alerts.append(
            _alert(
                "release_labels_pending",
                "warning",
                "候选命中仍有待人工复核样本，发布不会晋级。",
                "由非发布发起人完成确认或误报标注。",
            )
        )
    if int(metrics.get("candidate_oldest_pending_age_seconds") or 0) >= 86_400:
        alerts.append(
            _alert(
                "release_labels_overdue",
                "error",
                "最早待复核样本已超过 24 小时。",
                "安排独立复核人处理积压；完成前保持候选版本不晋级。",
            )
        )
    if int(metrics.get("negative_pending_label_count") or 0) > 0:
        alerts.append(
            _alert(
                "release_negative_audit_pending",
                "warning",
                "独立负样本盲审仍有积压，召回率证据尚未闭合。",
                "完成抽样单据核验；复核界面不会展示候选规则的原始结论。",
            )
        )
    negative_status = str(metrics.get("negative_ground_truth_status") or "")
    if negative_status in {
        "unavailable_no_random_negative_samples",
        "insufficient_random_negative_reviews",
    }:
        alerts.append(
            _alert(
                "release_negative_audit_insufficient",
                "info",
                "随机负样本数量尚不足以形成可信召回率下界。",
                "继续采集真实流量并完成系统选中的盲审样本。",
            )
        )
    if "precision_below_threshold" in reason_set or "precision_regression_exceeded" in reason_set:
        alerts.append(
            _alert(
                "release_precision_degraded",
                "error",
                "候选规则精度低于门禁或相对基线明显下降。",
                "检查误报样本、规则条件和基线版本。",
            )
        )
    if "recall_lower_bound_below_threshold" in reason_set:
        alerts.append(
            _alert(
                "release_recall_degraded",
                "critical",
                "候选规则的召回率保守下界低于发布门禁。",
                "检查已确认漏检样本，修正规则后重新进入影子发布。",
            )
        )
    if metrics.get("baseline_precision") is None:
        alerts.append(
            _alert(
                "baseline_precision_unavailable",
                "info",
                "当前没有完整的基线精度证据。",
                "继续采集基线命中并完成可信标注。",
            )
        )
    if status == "collecting" and int(metrics.get("observed_count") or 0) == 0:
        alerts.append(
            _alert(
                "release_observations_pending",
                "info",
                "当前发布阶段尚未采集到真实运行样本。",
                "保持稳定版本并等待真实流量覆盖。",
            )
        )
    return alerts


def _alert(code: str, severity: str, message: str, action: str) -> dict[str, str]:
    return {
        "code": code,
        "severity": severity,
        "message": message,
        "recommended_action": action,
    }
