"""Operator-facing alert outcome contract.

This module is intentionally generic: it converts the existing truth-chain
stage, automation quality verdict, and remediation evidence state into one
small contract that Telegram, AwoooP, and result notifications can all share.
"""

from __future__ import annotations

from typing import Any

_ACTION_REQUIRED_CHANNELS = ("telegram_sre_war_room", "awooop_operator_console")
_RESULT_ONLY_CHANNELS = ("telegram_result_reply", "awooop_operator_console")


def _safe_int(value: Any) -> int:
    try:
        return int(value or 0)
    except (TypeError, ValueError):
        return 0


def _first_text(values: list[Any]) -> str | None:
    for value in values:
        if value:
            return str(value)
    return None


def _build_notification(
    *,
    mode: str,
    channels: tuple[str, ...],
    reason: str,
    source_id: str | None,
) -> dict[str, Any]:
    return {
        "mode": mode,
        "channels": list(channels),
        "reason": reason,
        "source_id": source_id,
        "telegram": (
            "reply_to_original_or_standalone_action_required"
            if mode == "action_required"
            else "reply_to_original_or_standalone_result"
        ),
        "awooop": "status_chain_panel",
    }


def _build_execution_result(
    *,
    state: str,
    verdict: str,
    stage: str,
    has_repair_execution: bool,
    has_nonrepair_operation: bool,
    verification: str,
) -> dict[str, Any]:
    """Describe execution completion separately from remediation outcome."""
    approval_status = "unknown"
    completion_status = "unknown"
    command_status = "unknown"
    repair_status = "unknown"
    failure_status = "unknown"
    summary = "尚未能判定執行是否完成或失敗"
    terminal = False

    if state == "completed_verified":
        approval_status = "completed"
        completion_status = "completed_verified"
        command_status = "succeeded"
        repair_status = "verified_repaired"
        failure_status = "no_failure"
        summary = "已完成：修復指令成功，且驗證通過"
        terminal = True
    elif state == "execution_failed_manual_required":
        approval_status = "completed"
        completion_status = "failed"
        command_status = "failed"
        repair_status = "failed"
        failure_status = "command_failed"
        summary = "已失敗：修復指令執行失敗，需人工接手"
        terminal = True
    elif state == "diagnostic_only_manual_review":
        approval_status = "completed"
        completion_status = "completed_no_repair"
        command_status = "diagnostic_completed" if has_nonrepair_operation else "skipped_no_action"
        repair_status = "not_executed"
        failure_status = "no_command_failed"
        summary = "流程已完成：只完成診斷/觀察，沒有修復指令成功或失敗"
        terminal = True
    elif state == "verification_degraded_manual_required":
        approval_status = "completed"
        completion_status = "completed_verification_degraded"
        command_status = "succeeded" if has_repair_execution else "diagnostic_completed"
        repair_status = "verification_degraded"
        failure_status = "no_command_failed"
        summary = "已執行，但驗證結果退化；需人工確認是否真的修復"
        terminal = False
    elif state == "execution_unverified_manual_required":
        approval_status = "completed"
        completion_status = "completed_unverified"
        command_status = "succeeded"
        repair_status = "unverified"
        failure_status = "no_command_failed"
        summary = "已執行成功，但缺少修復驗證結果"
        terminal = False
    elif state == "no_action_manual_review":
        approval_status = "pending_manual_review"
        completion_status = "not_started_no_action"
        command_status = "not_started"
        repair_status = "not_executed"
        failure_status = "not_applicable"
        summary = "尚未執行：AI 建議不修復，等待人工決定是否接手"
        terminal = False
    elif state == "approval_rejected_no_execution":
        approval_status = "rejected"
        completion_status = "closed_no_execution"
        command_status = "not_run"
        repair_status = "not_executed"
        failure_status = "not_applicable"
        summary = "已拒絕：審批結案，未執行任何修復指令"
        terminal = True
    elif state == "approval_expired_manual_review":
        approval_status = "expired"
        completion_status = "expired_no_execution"
        command_status = "not_run"
        repair_status = "not_executed"
        failure_status = "not_applicable"
        summary = "審批逾期：未執行修復，需人工重新審查"
        terminal = False
    elif state == "approval_required":
        approval_status = "pending"
        completion_status = "pending_approval"
        command_status = "not_started"
        repair_status = "not_executed"
        failure_status = "not_applicable"
        summary = "尚未執行：等待人工批准"
        terminal = False
    elif state == "read_only_dry_run_manual_gate":
        approval_status = "manual_gate"
        completion_status = "dry_run_completed"
        command_status = "dry_run_succeeded"
        repair_status = "not_executed"
        failure_status = "not_applicable"
        summary = "只讀試跑完成，尚未執行修復"
        terminal = False
    elif state == "observed_not_executed":
        approval_status = "not_required"
        completion_status = "observed_not_executed"
        command_status = "not_run"
        repair_status = "not_executed"
        failure_status = "not_applicable"
        summary = "只完成收件/觀測，尚未進入執行"
        terminal = False
    elif has_repair_execution:
        approval_status = "completed"
        completion_status = "completed_needs_review"
        command_status = "succeeded" if verification != "missing" else "completed"
        repair_status = "needs_review"
        failure_status = "no_command_failed"
        summary = "已有執行紀錄，但仍需人工確認最終修復結果"
        terminal = False
    elif verdict in {"received_only", "observed_not_executed"} or stage == "received":
        approval_status = "not_started"
        completion_status = "not_started"
        command_status = "not_started"
        repair_status = "not_executed"
        failure_status = "not_applicable"
        summary = "尚未執行修復指令"
        terminal = False

    return {
        "approval_status": approval_status,
        "completion_status": completion_status,
        "command_status": command_status,
        "repair_status": repair_status,
        "failure_status": failure_status,
        "terminal": terminal,
        "summary_zh": summary,
    }


def build_operator_outcome(
    *,
    truth_status: dict[str, Any] | None = None,
    automation_quality: dict[str, Any] | None = None,
    remediation_state: str | None = None,
    fetch_error: str | None = None,
    source_id: str | None = None,
) -> dict[str, Any]:
    """Build a normalized operator outcome for an alert/incident.

    The output deliberately answers three questions:
    1. What happened?
    2. Does a human need to intervene?
    3. How will that human be notified / where should they act?
    """
    truth_status = truth_status or {}
    automation_quality = automation_quality or {}
    facts = automation_quality.get("facts")
    if not isinstance(facts, dict):
        facts = {}

    verdict = str(automation_quality.get("verdict") or "unknown")
    stage = str(truth_status.get("current_stage") or "unknown")
    stage_status = str(truth_status.get("stage_status") or "unknown")
    blockers = [
        str(item)
        for item in [
            *(truth_status.get("blockers") if isinstance(truth_status.get("blockers"), list) else []),
            *(automation_quality.get("blockers") if isinstance(automation_quality.get("blockers"), list) else []),
        ]
        if item
    ]
    verification = str(facts.get("verification_result") or "missing")
    has_repair_execution = _safe_int(facts.get("effective_execution_records")) > 0 or _safe_int(
        facts.get("auto_repair_execution_records")
    ) > 0
    has_nonrepair_operation = (
        _safe_int(facts.get("automation_operation_records")) > 0
        and not has_repair_execution
    )
    needs_human_from_truth = bool(truth_status.get("needs_human"))
    first_blocker = _first_text(blockers)

    if fetch_error:
        state = "truth_chain_unavailable"
        severity = "warning"
        needs_human = True
        next_action = "open_awooop_and_review_source_records"
        summary = "真相鏈查詢失敗，需人工確認處置結果"
        reason = str(fetch_error)[:240]
    elif verdict == "auto_repaired_verified":
        state = "completed_verified"
        severity = "success"
        needs_human = False
        next_action = "monitor_for_regression"
        summary = "已驗證自動修復完成"
        reason = "execution_and_verification_succeeded"
    elif verdict == "execution_failed" or stage == "execution_failed":
        state = "execution_failed_manual_required"
        severity = "critical"
        needs_human = True
        next_action = "manual_fix_or_rollback"
        summary = "執行失敗，需人工介入"
        reason = first_blocker or "execution_failed"
    elif verdict == "manual_required_diagnostic_only" or has_nonrepair_operation:
        state = "diagnostic_only_manual_review"
        severity = "warning"
        needs_human = True
        next_action = "manual_review_or_collect_repair_evidence"
        summary = "只完成診斷/觀察，尚未證明修復"
        reason = first_blocker or "diagnostic_or_audit_only"
    elif verdict == "auto_repaired_verification_degraded":
        state = "verification_degraded_manual_required"
        severity = "warning"
        needs_human = True
        next_action = "manual_verify_or_repair"
        summary = "已執行但驗證退化，需人工確認"
        reason = first_blocker or f"verification={verification}"
    elif verdict == "execution_unverified" or (
        has_repair_execution and verification == "missing"
    ):
        state = "execution_unverified_manual_required"
        severity = "warning"
        needs_human = True
        next_action = "run_or_review_post_execution_verification"
        summary = "已執行但缺少驗證結果，需人工確認"
        reason = first_blocker or "execution_without_verification_result"
    elif verdict == "manual_required_no_action":
        state = "no_action_manual_review"
        severity = "warning"
        needs_human = True
        next_action = "manual_review_no_action_decision"
        summary = "AI 選擇不執行修復，需人工判斷是否接手"
        reason = first_blocker or "no_action_or_observe"
    elif verdict == "approval_rejected_no_execution" or stage == "approval_rejected":
        state = "approval_rejected_no_execution"
        severity = "info"
        needs_human = False
        next_action = "monitor_or_reopen_if_alert_recurs"
        summary = "已拒絕處置，未執行修復"
        reason = "approval_rejected"
    elif verdict == "approval_expired_manual_review" or stage == "approval_expired":
        state = "approval_expired_manual_review"
        severity = "warning"
        needs_human = True
        next_action = "reopen_close_or_escalate_expired_approval"
        summary = "審批已逾期，需人工重新審查"
        reason = first_blocker or "approval_expired"
    elif remediation_state == "read_only":
        state = "read_only_dry_run_manual_gate"
        severity = "warning"
        needs_human = True
        next_action = "approve_or_escalate_from_awooop"
        summary = "只讀試跑完成，等待人工放行或轉交"
        reason = first_blocker or "read_only_dry_run"
    elif remediation_state == "write_observed":
        state = "write_observed_manual_review"
        severity = "critical"
        needs_human = True
        next_action = "review_write_evidence"
        summary = "補救證據出現寫入旗標，需人工確認"
        reason = first_blocker or "write_observed"
    elif remediation_state in {"blocked", "fetch_failed"}:
        state = "blocked_manual_required"
        severity = "critical" if remediation_state == "blocked" else "warning"
        needs_human = True
        next_action = "manual_investigation"
        summary = "自動化流程受阻，需人工處理"
        reason = first_blocker or remediation_state
    elif verdict == "approval_required" or stage == "approval_required":
        state = "approval_required"
        severity = "warning"
        needs_human = True
        next_action = "approve_reject_or_escalate"
        summary = "等待人工審批，尚未執行"
        reason = first_blocker or "pending_human_approval"
    elif needs_human_from_truth:
        state = "manual_required"
        severity = "warning"
        needs_human = True
        next_action = "manual_investigation"
        summary = "真相鏈判定需人工介入"
        reason = first_blocker or f"{stage}/{stage_status}"
    elif verdict in {"observed_not_executed", "received_only"}:
        state = "observed_not_executed"
        severity = "info"
        needs_human = False
        next_action = "collect_evidence_or_wait"
        summary = "已收到/觀測，尚未進入修復執行"
        reason = first_blocker or verdict
    else:
        state = "unknown_pending_observation"
        severity = "warning"
        needs_human = bool(blockers)
        next_action = "review_status_chain"
        summary = "處置結果尚未形成明確結論"
        reason = first_blocker or f"{verdict}:{stage}/{stage_status}"

    execution_result = _build_execution_result(
        state=state,
        verdict=verdict,
        stage=stage,
        has_repair_execution=has_repair_execution,
        has_nonrepair_operation=has_nonrepair_operation,
        verification=verification,
    )
    mode = "action_required" if needs_human else "result_only"
    channels = _ACTION_REQUIRED_CHANNELS if needs_human else _RESULT_ONLY_CHANNELS
    return {
        "schema_version": "operator_outcome_v1",
        "state": state,
        "severity": severity,
        "summary_zh": summary,
        "needs_human": needs_human,
        "human_action_required": needs_human,
        "human_action_reason": reason,
        "next_action": next_action,
        "execution_result": execution_result,
        "notification": _build_notification(
            mode=mode,
            channels=channels,
            reason=reason,
            source_id=source_id,
        ),
        "evidence": {
            "verdict": verdict,
            "current_stage": stage,
            "stage_status": stage_status,
            "verification": verification,
            "auto_repair_execution_records": _safe_int(
                facts.get("auto_repair_execution_records")
            ),
            "effective_execution_records": _safe_int(
                facts.get("effective_execution_records")
            ),
            "automation_operation_records": _safe_int(
                facts.get("automation_operation_records")
            ),
            "mcp_gateway_total": _safe_int(facts.get("mcp_gateway_total")),
            "knowledge_entries": _safe_int(facts.get("knowledge_entries")),
        },
        "blockers": blockers[:8],
    }
