"""
P2-406B AI Agent receipt readback owner review snapshot.

Loads the latest committed, read-only owner review surface that links daily /
weekly / monthly reports, Telegram receipt review, P2-004 supply-chain drift,
and P2-403J report-truth gates. This service intentionally does not send
Telegram messages, write Gateway queues, call the Bot API, read secrets, run
AI analysis workers, or mutate production.
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any

from src.services.snapshot_paths import default_evaluations_dir

_DEFAULT_EVALUATIONS_DIR = default_evaluations_dir(Path(__file__))
_SNAPSHOT_PATTERN = "ai_agent_receipt_readback_owner_review_*.json"
_SCHEMA_VERSION = "ai_agent_receipt_readback_owner_review_v1"
_RUNTIME_AUTHORITY = "receipt_readback_owner_review_only_no_send_or_write"
_EXPECTED_CURRENT_TASK = "P2-406B"
_EXPECTED_NEXT_TASK = "P2-407"
_EXPECTED_CANONICAL_ROOM = "AwoooI SRE 戰情室"
_EXPECTED_CANONICAL_ROOM_ENV = "SRE_GROUP_CHAT_ID"
_EXPECTED_SOURCE_SCHEMAS = {
    "ai_agent_report_status_board_v1",
    "ai_agent_report_live_delivery_approval_package_v1",
    "ai_agent_telegram_receipt_approval_package_v1",
    "ai_agent_professional_task_expansion_v1",
    "dependency_supply_chain_drift_monitor_v1",
    "ai_agent_report_truth_actionability_review_v1",
}
_FALSE_BOUNDARY_FLAGS = {
    "scheduler_enabled",
    "gateway_queue_write_enabled",
    "telegram_send_enabled",
    "bot_api_call_enabled",
    "delivery_receipt_write_enabled",
    "report_receipt_write_enabled",
    "receipt_production_write_enabled",
    "ai_analysis_run_enabled",
    "medium_low_auto_execution_enabled",
    "production_optimization_write_enabled",
    "production_write_enabled",
    "secret_read_enabled",
    "paid_api_enabled",
    "host_write_enabled",
    "kubectl_action_enabled",
    "destructive_operation_enabled",
    "external_lookup_enabled",
}
_TRUE_BOUNDARY_FLAGS = {
    "owner_review_required_before_canary",
    "read_only_review_allowed",
}
_ZERO_ROLLUP_FIELDS = {
    "live_write_count",
    "telegram_send_count",
    "gateway_queue_write_count",
    "bot_api_call_count",
    "production_write_count",
    "secret_read_count",
    "paid_api_call_count",
    "host_write_count",
    "kubectl_action_count",
}
_FORBIDDEN_PUBLIC_TERMS = {
    "工作視窗",
    "對話內容",
    "批准！繼續",
    "In app browser",
    "My request for Codex",
    "browser_context",
    "codex_user_message",
    "prompt_text",
    "chain_of_thought",
    "chain-of-thought",
    "private reasoning",
    "authorization_header",
    "authorization header",
    "secret_value",
    "secret value",
    "raw_payload",
    "raw prompt",
    "telegram token",
}


def load_latest_ai_agent_receipt_readback_owner_review(
    evaluations_dir: Path | None = None,
) -> dict[str, Any]:
    """Load the newest committed P2-406B receipt readback owner review."""
    directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR
    candidates = sorted(directory.glob(_SNAPSHOT_PATTERN))
    if not candidates:
        raise FileNotFoundError(
            f"no AI Agent receipt readback owner review snapshots found in {directory}"
        )

    latest = candidates[-1]
    with latest.open(encoding="utf-8") as handle:
        payload = json.load(handle)

    if not isinstance(payload, dict):
        raise ValueError(f"{latest}: expected JSON object")

    label = str(latest)
    _require_schema(payload, label)
    _require_source_readbacks(payload, label)
    _require_receipt_readback_plan(payload, label)
    _require_owner_review_gates(payload, label)
    _require_drift_and_report_truth(payload, label)
    _require_activation_boundaries(payload, label)
    _require_rollups(payload, label)
    _require_no_forbidden_public_terms(payload, label)
    return payload


def _require_schema(payload: dict[str, Any], label: str) -> None:
    if payload.get("schema_version") != _SCHEMA_VERSION:
        raise ValueError(f"{label}: expected schema_version={_SCHEMA_VERSION}")

    status = payload.get("program_status") or {}
    expected = {
        "overall_completion_percent": 100,
        "current_priority": "P2",
        "current_task_id": _EXPECTED_CURRENT_TASK,
        "next_task_id": _EXPECTED_NEXT_TASK,
        "read_only_mode": True,
        "runtime_authority": _RUNTIME_AUTHORITY,
    }
    mismatches = _mismatches(status, expected)
    if mismatches:
        raise ValueError(f"{label}: program_status mismatch: {mismatches}")
    if not status.get("status_note"):
        raise ValueError(f"{label}: program_status.status_note is required")


def _require_source_readbacks(payload: dict[str, Any], label: str) -> None:
    source_refs = payload.get("source_refs") or []
    readbacks = payload.get("source_readbacks") or []
    if not source_refs:
        raise ValueError(f"{label}: source_refs must not be empty")
    if len(readbacks) < len(_EXPECTED_SOURCE_SCHEMAS):
        raise ValueError(f"{label}: source_readbacks must include all required sources")

    schemas = {item.get("source_schema_version") for item in readbacks}
    missing = sorted(_EXPECTED_SOURCE_SCHEMAS - schemas)
    if missing:
        raise ValueError(f"{label}: missing source readback schemas: {missing}")

    for item in readbacks:
        readback_id = item.get("readback_id") or "<missing>"
        for field in ("source_ref", "endpoint", "owner_agent", "status", "evidence_status", "key_readback", "next_action"):
            if not item.get(field):
                raise ValueError(f"{label}: source readback {readback_id} missing {field}")


def _require_receipt_readback_plan(payload: dict[str, Any], label: str) -> None:
    plan = payload.get("receipt_readback_plan") or {}
    expected = {
        "canonical_room": _EXPECTED_CANONICAL_ROOM,
        "canonical_room_env": _EXPECTED_CANONICAL_ROOM_ENV,
        "gateway_owner": "telegram_ops",
        "arbiter": "openclaw",
        "receipt_owner": "hermes",
        "replay_owner": "nemotron",
        "dry_run_receipt_only": True,
        "owner_review_required_before_canary": True,
        "canary_send_approved": False,
        "receipt_production_write_enabled": False,
    }
    mismatches = _mismatches(plan, expected)
    if mismatches:
        raise ValueError(f"{label}: receipt_readback_plan mismatch: {mismatches}")

    checks = plan.get("readback_checks") or []
    if len(checks) != 8:
        raise ValueError(f"{label}: receipt_readback_plan.readback_checks must contain 8 checks")
    for check in checks:
        check_id = check.get("check_id") or "<missing>"
        if not check.get("evidence_refs"):
            raise ValueError(f"{label}: readback check {check_id} must include evidence_refs")
        if not check.get("blocked_runtime_action"):
            raise ValueError(f"{label}: readback check {check_id} must include blocked_runtime_action")

    telegram_policy = payload.get("telegram_policy") or {}
    expected_policy = {
        "canonical_room": _EXPECTED_CANONICAL_ROOM,
        "canonical_room_env": _EXPECTED_CANONICAL_ROOM_ENV,
        "gateway_queue_write_allowed": False,
        "direct_bot_api_allowed": False,
        "telegram_send_allowed": False,
        "receipt_write_allowed": False,
    }
    policy_mismatches = _mismatches(telegram_policy, expected_policy)
    if policy_mismatches:
        raise ValueError(f"{label}: telegram_policy mismatch: {policy_mismatches}")


def _require_owner_review_gates(payload: dict[str, Any], label: str) -> None:
    gates = payload.get("owner_review_gates") or []
    if len(gates) != 6:
        raise ValueError(f"{label}: owner_review_gates must contain 6 gates")

    for gate in gates:
        gate_id = gate.get("gate_id") or "<missing>"
        if gate.get("approval_required") is not True:
            raise ValueError(f"{label}: owner review gate {gate_id} must require approval")
        if gate.get("status") != "owner_review_required":
            raise ValueError(f"{label}: owner review gate {gate_id} must remain owner_review_required")
        for field in (
            "required_owner_fields",
            "acceptance_checks",
            "rejection_reasons",
            "blocked_runtime_actions",
            "evidence_refs",
        ):
            if not gate.get(field):
                raise ValueError(f"{label}: owner review gate {gate_id} missing {field}")


def _require_drift_and_report_truth(payload: dict[str, Any], label: str) -> None:
    drift = payload.get("drift_monitor_owner_review") or {}
    expected_drift = {
        "source_task_id": "P2-004",
        "drift_candidate_count": 9,
        "action_required_candidate_count": 9,
        "external_lookup_allowed": False,
        "package_upgrade_allowed": False,
    }
    drift_mismatches = _mismatches(drift, expected_drift)
    if drift_mismatches:
        raise ValueError(f"{label}: drift_monitor_owner_review mismatch: {drift_mismatches}")
    if not drift.get("owner_actions"):
        raise ValueError(f"{label}: drift_monitor_owner_review.owner_actions must not be empty")

    report_truth = payload.get("report_truth_owner_review") or {}
    expected_truth = {
        "source_task_id": "P2-403J",
        "all_zero_weekly_report_is_actionable_anomaly": True,
        "all_zero_weekly_report_confidence": "low_trust_actionable_anomaly",
        "zero_signal_finding_count": 5,
        "telegram_report_send_allowed": False,
        "cronjob_change_allowed": False,
        "freshness_gate_implemented": False,
        "source_confidence_gate_implemented": False,
        "actionability_score_implemented": False,
    }
    truth_mismatches = _mismatches(report_truth, expected_truth)
    if truth_mismatches:
        raise ValueError(f"{label}: report_truth_owner_review mismatch: {truth_mismatches}")
    if not report_truth.get("owner_actions"):
        raise ValueError(f"{label}: report_truth_owner_review.owner_actions must not be empty")


def _require_activation_boundaries(payload: dict[str, Any], label: str) -> None:
    boundaries = payload.get("activation_boundaries") or {}
    wrong_true = sorted(flag for flag in _TRUE_BOUNDARY_FLAGS if boundaries.get(flag) is not True)
    if wrong_true:
        raise ValueError(f"{label}: activation boundaries must remain true: {wrong_true}")

    wrong_false = sorted(flag for flag in _FALSE_BOUNDARY_FLAGS if boundaries.get(flag) is not False)
    if wrong_false:
        raise ValueError(f"{label}: activation boundaries must remain false: {wrong_false}")


def _require_rollups(payload: dict[str, Any], label: str) -> None:
    rollups = payload.get("rollups") or {}
    report_cadences = (payload.get("report_owner_review") or {}).get("cadences") or []
    readback_checks = (payload.get("receipt_readback_plan") or {}).get("readback_checks") or []
    owner_review_gates = payload.get("owner_review_gates") or []
    source_readbacks = payload.get("source_readbacks") or []
    boundaries = payload.get("activation_boundaries") or {}
    drift = payload.get("drift_monitor_owner_review") or {}
    report_truth = payload.get("report_truth_owner_review") or {}

    expected_counts = {
        "source_readback_count": len(source_readbacks),
        "report_cadence_count": len(report_cadences),
        "owner_review_gate_count": len(owner_review_gates),
        "receipt_readback_check_count": len(readback_checks),
        "drift_candidate_count": drift.get("drift_candidate_count"),
        "report_truth_blocker_count": report_truth.get("zero_signal_finding_count"),
        "approval_required_count": sum(1 for gate in owner_review_gates if gate.get("approval_required") is True),
        "blocked_runtime_action_count": sum(1 for flag in _FALSE_BOUNDARY_FLAGS if boundaries.get(flag) is False),
    }
    mismatched = {
        key: {"expected": expected, "actual": rollups.get(key)}
        for key, expected in expected_counts.items()
        if rollups.get(key) != expected
    }
    if mismatched:
        raise ValueError(f"{label}: rollup counts must match payload sections: {mismatched}")

    non_zero = sorted(field for field in _ZERO_ROLLUP_FIELDS if rollups.get(field) != 0)
    if non_zero:
        raise ValueError(f"{label}: rollup live/write counters must remain zero: {non_zero}")


def _require_no_forbidden_public_terms(payload: Any, label: str) -> None:
    offenders: list[str] = []

    def visit(value: Any, path: str) -> None:
        if isinstance(value, dict):
            for key, child in value.items():
                visit(child, f"{path}.{key}")
        elif isinstance(value, list):
            for index, child in enumerate(value):
                visit(child, f"{path}[{index}]")
        elif isinstance(value, str):
            lowered = value.lower()
            for term in _FORBIDDEN_PUBLIC_TERMS:
                if term.lower() in lowered:
                    offenders.append(f"{path}: {term}")

    visit(payload, "$")
    if offenders:
        raise ValueError(f"{label}: forbidden public terms present: {offenders[:5]}")


def _mismatches(actual: dict[str, Any], expected: dict[str, Any]) -> dict[str, dict[str, Any]]:
    return {
        key: {"expected": expected_value, "actual": actual.get(key)}
        for key, expected_value in expected.items()
        if actual.get(key) != expected_value
    }
