"""
AI Agent report status board snapshot.

Loads the latest committed P2-108 daily / weekly / monthly report status board.
This module exposes a read-only management summary only. It never schedules
reports, sends Telegram, writes Gateway queues, records read receipts, starts
AI analysis workers, or writes production optimization results.
"""

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_report_status_board_*.json"
_SCHEMA_VERSION = "ai_agent_report_status_board_v1"
_RUNTIME_AUTHORITY = "report_status_board_only_no_live_send_or_write"
_FORBIDDEN_DISPLAY_TERMS = (
    "工作視窗",
    "對話內容",
    "批准！繼續",
    "In app browser",
    "My request for Codex",
    "browser_context",
    "codex_user_message",
    "prompt_text",
    "raw prompt",
    "raw_prompt",
    "private reasoning",
    "private_reasoning",
    "chain of thought",
    "chain_of_thought",
    "authorization_header",
    "authorization header",
    "secret value",
    "secret_value",
    "raw payload",
    "raw_payload",
    "raw Telegram payload",
    "raw_telegram_payload",
)


def load_latest_ai_agent_report_status_board(
    evaluations_dir: Path | None = None,
) -> dict[str, Any]:
    """Load the newest committed AI Agent report status board snapshot."""
    directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR
    candidates = sorted(directory.glob(_SNAPSHOT_PATTERN))
    if not candidates:
        raise FileNotFoundError(f"no AI Agent report status board 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")
    _require_schema(payload, str(latest))
    _require_completion_truth(payload, str(latest))
    _require_report_cards(payload, str(latest))
    _require_agent_status_reports(payload, str(latest))
    _require_visible_charts(payload, str(latest))
    _require_operator_answers(payload, str(latest))
    _require_activation_boundaries(payload, str(latest))
    _require_display_redaction(payload, str(latest))
    _require_no_forbidden_display_terms(payload, str(latest))
    _require_rollup_consistency(payload, str(latest))
    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 {}
    if status.get("read_only_mode") is not True:
        raise ValueError(f"{label}: program_status.read_only_mode must be true")
    if status.get("runtime_authority") != _RUNTIME_AUTHORITY:
        raise ValueError(f"{label}: runtime_authority must remain {_RUNTIME_AUTHORITY}")
    if status.get("current_task_id") != "P2-108":
        raise ValueError(f"{label}: current_task_id must be P2-108")
    if status.get("overall_completion_percent") != 100:
        raise ValueError(f"{label}: P2-108 status board must be 100 percent complete")


def _require_completion_truth(payload: dict[str, Any], label: str) -> None:
    truth = payload.get("report_completion_truth") or {}
    required_true = {
        "daily_report_visible",
        "weekly_report_visible",
        "monthly_report_visible",
        "per_agent_status_visible",
        "workload_metrics_visible",
        "chart_package_visible",
        "telegram_digest_draft_visible",
        "low_medium_high_controlled_apply_allowed",
        "critical_break_glass_required",
    }
    missing = sorted(field for field in required_true if truth.get(field) is not True)
    if missing:
        raise ValueError(f"{label}: report visibility truth flags must remain true: {missing}")

    required_false = {
        "live_report_delivery_enabled",
        "ai_post_report_analysis_enabled",
    }
    unsafe = sorted(field for field in required_false if truth.get(field) is not False)
    if unsafe:
        raise ValueError(f"{label}: live report automation flags must remain false: {unsafe}")

    zero_counts = {
        "live_telegram_send_count_24h",
        "live_auto_optimization_count_24h",
    }
    non_zero = sorted(field for field in zero_counts if truth.get(field) != 0)
    if non_zero:
        raise ValueError(f"{label}: live report counters must remain zero: {non_zero}")


def _require_report_cards(payload: dict[str, Any], label: str) -> None:
    cards = payload.get("report_status_cards") or []
    cadence_ids = {card.get("cadence_id") for card in cards}
    if cadence_ids != {"daily", "weekly", "monthly"}:
        raise ValueError(f"{label}: report cards must include daily, weekly, monthly")
    for card in cards:
        cadence_id = card.get("cadence_id")
        if card.get("completion_percent") != 100:
            raise ValueError(f"{label}: report {cadence_id} must be 100 percent visible")
        if card.get("contract_state") != "visible_contract_ready":
            raise ValueError(f"{label}: report {cadence_id} contract_state must be visible_contract_ready")
        if card.get("delivery_state") != "draft_only":
            raise ValueError(f"{label}: report {cadence_id} delivery_state must remain draft_only")
        if card.get("live_delivery_count") != 0:
            raise ValueError(f"{label}: report {cadence_id} live_delivery_count must remain zero")
        if not card.get("next_gate"):
            raise ValueError(f"{label}: report {cadence_id} must include next_gate")


def _require_agent_status_reports(payload: dict[str, Any], label: str) -> None:
    reports = payload.get("agent_status_reports") or []
    agent_ids = {report.get("agent_id") for report in reports}
    if agent_ids != {"openclaw", "hermes", "nemotron"}:
        raise ValueError(f"{label}: agent status reports must include OpenClaw, Hermes, NemoTron")
    for report in reports:
        agent_id = report.get("agent_id")
        total = report.get("work_units_total")
        done = report.get("work_units_done")
        waiting = report.get("work_units_waiting_approval")
        controlled = report.get("work_units_in_controlled_queue", 0)
        if not isinstance(total, int) or not isinstance(done, int) or not isinstance(waiting, int):
            raise ValueError(f"{label}: agent {agent_id} work units must be integers")
        if not isinstance(controlled, int):
            raise ValueError(f"{label}: agent {agent_id} controlled queue must be integer")
        if done + waiting + controlled != total:
            raise ValueError(f"{label}: agent {agent_id} done + waiting + controlled must equal total")
        if report.get("live_runtime_work_units_24h") != 0:
            raise ValueError(f"{label}: agent {agent_id} live_runtime_work_units_24h must remain zero")
        if not report.get("primary_role") or not report.get("status_note"):
            raise ValueError(f"{label}: agent {agent_id} must include role and status note")


def _require_visible_charts(payload: dict[str, Any], label: str) -> None:
    charts = payload.get("visible_charts") or []
    chart_ids = {chart.get("chart_id") for chart in charts}
    required = {"report_cadence_completion", "agent_workload_status", "runtime_activation_boundary"}
    if chart_ids != required:
        raise ValueError(f"{label}: visible charts must match {sorted(required)}")
    for chart in charts:
        if not chart.get("series"):
            raise ValueError(f"{label}: chart {chart.get('chart_id')} must include series")


def _require_operator_answers(payload: dict[str, Any], label: str) -> None:
    answers = payload.get("operator_answer_cards") or []
    answer_ids = {answer.get("answer_id") for answer in answers}
    required = {
        "daily_weekly_monthly_complete",
        "per_agent_status_visible",
        "telegram_and_auto_optimization_boundary",
        "high_risk_review_policy",
    }
    if answer_ids != required:
        raise ValueError(f"{label}: operator answers must match {sorted(required)}")
    complete_answers = [answer for answer in answers if answer.get("status") == "complete"]
    if len(complete_answers) < 2:
        raise ValueError(f"{label}: at least report and per-agent answers must be complete")


def _require_activation_boundaries(payload: dict[str, Any], label: str) -> None:
    boundaries = payload.get("activation_boundaries") or {}
    required_false = {
        "scheduler_enabled",
        "gateway_queue_write_enabled",
            "telegram_send_enabled",
            "report_receipt_write_enabled",
            "ai_analysis_run_enabled",
            "production_optimization_write_enabled",
        }
    unsafe = sorted(field for field in required_false if boundaries.get(field) is not False)
    if unsafe:
        raise ValueError(f"{label}: activation boundaries must remain false: {unsafe}")
    if boundaries.get("low_medium_high_controlled_apply_allowed") is not True:
        raise ValueError(f"{label}: low_medium_high_controlled_apply_allowed must remain true")
    if boundaries.get("high_risk_requires_human_approval") is not False:
        raise ValueError(f"{label}: high_risk_requires_human_approval must remain false")
    if boundaries.get("critical_break_glass_required") is not True:
        raise ValueError(f"{label}: critical_break_glass_required must remain true")


def _require_display_redaction(payload: dict[str, Any], label: str) -> None:
    contract = payload.get("display_redaction_contract") or {}
    if contract.get("redaction_required") is not True:
        raise ValueError(f"{label}: display redaction is required")
    forbidden_true = {
        "raw_prompt_display_allowed",
        "private_reasoning_display_allowed",
        "secret_value_display_allowed",
        "internal_transcript_display_allowed",
    }
    unsafe = sorted(field for field in forbidden_true if contract.get(field) is not False)
    if unsafe:
        raise ValueError(f"{label}: display redaction fields must remain false: {unsafe}")


def _require_no_forbidden_display_terms(payload: Any, label: str) -> None:
    strings = _collect_strings(payload)
    found = sorted({term for term in _FORBIDDEN_DISPLAY_TERMS for value in strings if term in value})
    if found:
        raise ValueError(f"{label}: forbidden display terms found: {found}")


def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
    rollups = payload.get("rollups") or {}
    report_cards = payload.get("report_status_cards") or []
    agents = payload.get("agent_status_reports") or []
    charts = payload.get("visible_charts") or []
    answers = payload.get("operator_answer_cards") or []
    expected = {
        "report_card_count": len(report_cards),
        "agent_status_count": len(agents),
        "visible_chart_count": len(charts),
        "operator_answer_count": len(answers),
        "completed_report_count": len([card for card in report_cards if card.get("completion_percent") == 100]),
        "workload_unit_total": sum(agent.get("work_units_total", 0) for agent in agents),
        "workload_done_total": sum(agent.get("work_units_done", 0) for agent in agents),
        "workload_waiting_approval_total": sum(agent.get("work_units_waiting_approval", 0) for agent in agents),
        "workload_controlled_queue_total": sum(agent.get("work_units_in_controlled_queue", 0) for agent in agents),
        "live_delivery_count": sum(card.get("live_delivery_count", 0) for card in report_cards),
        "live_telegram_send_count": 0,
        "live_runtime_work_units": sum(agent.get("live_runtime_work_units_24h", 0) for agent in agents),
        "live_auto_optimization_count": 0,
        "high_risk_requires_human_approval": False,
        "low_medium_high_controlled_apply_allowed": True,
        "critical_break_glass_required": True,
    }
    mismatched = {
        key: {"expected": value, "actual": rollups.get(key)}
        for key, value in expected.items()
        if rollups.get(key) != value
    }
    if mismatched:
        raise ValueError(f"{label}: rollup counts must match payload sections: {mismatched}")


def _collect_strings(value: Any) -> list[str]:
    if isinstance(value, str):
        return [value]
    if isinstance(value, list):
        strings: list[str] = []
        for item in value:
            strings.extend(_collect_strings(item))
        return strings
    if isinstance(value, dict):
        strings: list[str] = []
        for item in value.values():
            strings.extend(_collect_strings(item))
        return strings
    return []
