"""市場情報 MCP manual fetch handoff preview。

本模組只審核 runtime promotion 與操作員安全確認是否足以進入人工
fetch gate review；不打開 fetch、不連外、不開 DB、不保存 payload、不掛排程。
"""

from services.market_intel.mcp_fetch_gate import build_mcp_fetch_gate_preview
from services.market_intel.mcp_runtime_promotion import (
    build_mcp_runtime_promotion_preview,
)


ACKNOWLEDGEMENT_LABELS = {
    "public_pages_only": "只允許公開頁面與公開結構化資料",
    "respect_rate_limit": "每平台需遵守節流與 timeout / retry ceiling",
    "no_login_no_antibot": "不得登入、不得處理會員資料、不得繞反爬或帳號池",
    "no_database_write": "本階段不得寫 DB，正式入庫需另走 writer gate",
    "no_scheduler_attach": "不得掛上正式 scheduler，排程掛載另行批准",
    "manual_fetch_requires_separate_execution": "manual fetch 需另由人工命令或後續 gate 執行",
}

_BLOCKED_SIDE_EFFECT_KEYS = (
    "api_executes_health_check",
    "api_executes_docker",
    "api_executes_ssh",
    "api_opens_database_connection",
    "api_writes_database",
    "api_uses_external_network",
    "database_session_created",
    "database_write_executed",
    "database_commit_executed",
    "external_network_executed",
    "scheduler_attached",
    "writes_executed",
    "would_write_database",
)


def _default_runtime_status(phase):
    return {
        "phase": phase,
        "enabled": False,
        "crawler_enabled": False,
        "write_enabled": False,
        "dry_run_only": True,
        "scheduler_attached": False,
        "database_write_allowed": False,
    }


def _sample_handoff_package(promotion_review):
    return {
        "promotion_package": promotion_review["sample_promotion_package"],
        "operator_acknowledgements": {
            key: True for key in ACKNOWLEDGEMENT_LABELS
        },
    }


def _promotion_review_from_inputs(promotion_package, promotion_review, phase):
    if isinstance(promotion_review, dict) and promotion_review:
        return promotion_review

    promotion_package = promotion_package or {}
    return build_mcp_runtime_promotion_preview(
        activation_evidence=promotion_package.get("activation_evidence", {}),
        runtime_receipt=promotion_package.get("runtime_receipt", {}),
        phase=phase,
    )


def _side_effect_free(payload):
    return all(not payload.get(key) for key in _BLOCKED_SIDE_EFFECT_KEYS)


def build_mcp_manual_fetch_handoff_preview(
    *,
    promotion_package=None,
    promotion_review=None,
    operator_acknowledgements=None,
    runtime_status=None,
    phase=None,
):
    """建立 manual fetch handoff review；只輸出審核結果，不執行 fetch。"""
    promotion_package = promotion_package or {}
    operator_acknowledgements = operator_acknowledgements or {}
    review = _promotion_review_from_inputs(
        promotion_package,
        promotion_review,
        phase,
    )
    fetch_gate = build_mcp_fetch_gate_preview(
        runtime_status or _default_runtime_status(phase),
        fetch_requested=False,
        execute_readiness=False,
    )
    fetch_gate["phase"] = phase

    handoff_payload_received = bool(
        promotion_package or promotion_review or operator_acknowledgements
    )
    acknowledgement_status = {
        key: {
            "label": label,
            "acknowledged": bool(operator_acknowledgements.get(key)),
        }
        for key, label in ACKNOWLEDGEMENT_LABELS.items()
    }
    acknowledgement_complete = all(
        item["acknowledged"] for item in acknowledgement_status.values()
    )
    promotion_accepted = bool(review.get("runtime_promotion_accepted"))
    fetch_gate_closed = bool(
        not fetch_gate.get("manual_fetch_gate_open")
        and not fetch_gate.get("network_request_allowed")
        and not fetch_gate.get("external_network_executed")
    )
    side_effect_free = bool(
        _side_effect_free(review)
        and _side_effect_free(fetch_gate)
    )

    gates = [
        {
            "key": "runtime_promotion_payload_or_review_received",
            "passed": bool(promotion_package or promotion_review),
            "label": "已提供 runtime promotion package 或已審核結果",
        },
        {
            "key": "runtime_promotion_accepted",
            "passed": promotion_accepted,
            "label": "runtime promotion 已通過，可進下一段人工交接",
        },
        {
            "key": "operator_acknowledgements_complete",
            "passed": acknowledgement_complete,
            "label": "操作員已確認公開頁面、節流、無登入、無 DB、無排程邊界",
        },
        {
            "key": "fetch_gate_preview_present",
            "passed": bool(fetch_gate.get("mode") == "mcp_fetch_gate_planned"),
            "label": "已產生 fetch gate planned preview",
        },
        {
            "key": "fetch_gate_remains_closed_by_api",
            "passed": fetch_gate_closed,
            "label": "本 API 不打開 fetch、不允許 network request",
        },
        {
            "key": "handoff_side_effect_free",
            "passed": side_effect_free,
            "label": "handoff 審核不打 health、不開 DB、不連外、不掛 scheduler",
        },
    ]
    gates.extend(
        {
            "key": f"ack_{key}",
            "passed": item["acknowledged"],
            "label": item["label"],
        }
        for key, item in acknowledgement_status.items()
    )
    blocked_reasons = [
        gate["key"] for gate in gates
        if not gate["passed"]
    ]
    accepted = bool(handoff_payload_received and not blocked_reasons)

    return {
        "mode": (
            "mcp_manual_fetch_handoff_review"
            if handoff_payload_received
            else "mcp_manual_fetch_handoff_preview"
        ),
        "phase": phase,
        "handoff_payload_received": handoff_payload_received,
        "promotion_payload_received": bool(promotion_package or promotion_review),
        "operator_acknowledgements_received": bool(operator_acknowledgements),
        "runtime_promotion_accepted": promotion_accepted,
        "operator_acknowledgements_complete": acknowledgement_complete,
        "manual_fetch_handoff_accepted": accepted,
        "ready_for_manual_fetch_gate_operator_review": accepted,
        "manual_fetch_gate_opened_by_api": False,
        "network_request_allowed": False,
        "fetch_executed": False,
        "gate_count": len(gates),
        "passed_gate_count": sum(1 for gate in gates if gate["passed"]),
        "blocked_reasons": blocked_reasons,
        "gates": gates,
        "operator_acknowledgement_status": acknowledgement_status,
        "promotion_summary": {
            "mode": review.get("mode"),
            "accepted": promotion_accepted,
            "passed_gate_count": review.get("passed_gate_count", 0),
            "gate_count": review.get("gate_count", 0),
            "blocked_reasons": review.get("blocked_reasons", []),
            "ready_for_manual_fetch_gate_review": bool(
                review.get("ready_for_manual_fetch_gate_review")
            ),
        },
        "fetch_gate_summary": {
            "mode": fetch_gate.get("mode"),
            "manual_fetch_gate_open": bool(fetch_gate.get("manual_fetch_gate_open")),
            "network_request_allowed": bool(fetch_gate.get("network_request_allowed")),
            "blocked_reasons": fetch_gate.get("blocked_reasons", []),
        },
        "mcp_runtime_promotion": review,
        "mcp_fetch_gate": fetch_gate,
        "sample_handoff_package": _sample_handoff_package(review),
        "next_operator_steps": [
            "若 handoff 通過，只代表可進入人工 fetch gate 審核，不代表 API 可直接抓取",
            "操作員仍需確認公開頁面範圍、限速策略、紀錄保存與回退方式",
            "正式 DB write、scheduler attach、Telegram/AI 摘要仍需各自獨立 gate",
        ],
        "payload_persisted": False,
        "handoff_persisted": False,
        "api_executes_health_check": False,
        "api_executes_docker": False,
        "api_executes_ssh": False,
        "api_opens_database_connection": False,
        "api_writes_database": False,
        "api_uses_external_network": False,
        "database_session_created": False,
        "database_write_executed": False,
        "database_commit_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "writes_executed": False,
        "would_write_database": False,
    }
