"""候選審核 queue writer operator run package preview。

本模組只把正式 CLI 小流量寫入前需要保存的 payload、命令、證據與
回退資訊整理成可審核預覽；不讀 approval token、不寫本機檔案、不開 DB
connection、不執行 CLI、不 commit、不掛 scheduler。
"""

import hashlib
import json


def _stable_hash(value):
    encoded = json.dumps(
        value,
        ensure_ascii=False,
        sort_keys=True,
        separators=(",", ":"),
    ).encode("utf-8")
    return hashlib.sha256(encoded).hexdigest()


def _statement_payloads(transaction_preview):
    payloads = []
    for statement in transaction_preview.get("statements", []):
        payload = statement.get("parameter_preview")
        if not isinstance(payload, dict):
            continue
        payloads.append(
            {
                "index": statement.get("index"),
                "idempotency_key": statement.get("idempotency_key"),
                "dedupe_key": payload.get("dedupe_key"),
                "alert_candidate_id": payload.get("alert_candidate_id"),
                "review_state": payload.get("review_state"),
                "priority_lane": payload.get("priority_lane"),
                "threshold_level": payload.get("threshold_level"),
                "source_batch_id": payload.get("source_batch_id"),
                "payload_hash": _stable_hash(payload),
            }
        )
    return payloads


def _package_gates(
    *,
    transaction_preview,
    writer_preflight,
    writer_status,
    postwrite_smoke,
    operator_drill,
):
    transaction_summary = transaction_preview.get("transaction_summary", {})
    statement_count = int(transaction_summary.get("statement_count") or 0)
    return [
        {
            "key": "transaction_preview_created",
            "label": "已產生 candidate queue transaction preview",
            "passed": bool(transaction_preview.get("transaction_preview_created")),
        },
        {
            "key": "transaction_has_one_small_batch",
            "label": "首次 operator run 必須是小流量，且至少有一筆 statement",
            "passed": 0 < statement_count <= 5,
        },
        {
            "key": "writer_preflight_planned",
            "label": "已建立 writer preflight 計畫，正式操作時需另跑只讀 smoke",
            "passed": bool(writer_preflight),
        },
        {
            "key": "writer_cli_gate_available",
            "label": "CLI writer gate 已可用，正式寫入只能走 CLI",
            "passed": bool(writer_status),
        },
        {
            "key": "postwrite_smoke_available",
            "label": "post-write smoke 已可用，寫入後可只讀驗證 dedupe key",
            "passed": bool(postwrite_smoke),
        },
        {
            "key": "operator_drill_ready",
            "label": "operator drill 已產生正式操作順序",
            "passed": bool(operator_drill.get("operator_drill_ready")),
        },
        {
            "key": "real_sample_payload_saved_by_operator",
            "label": "真實 sample result 必須由操作員存成 reviewed JSON 檔",
            "passed": False,
        },
        {
            "key": "backup_artifact_path_recorded",
            "label": "正式寫入前必須記錄最新備份檔路徑",
            "passed": False,
        },
        {
            "key": "one_time_token_supplied_in_shell_only",
            "label": "一次性 approval token 只能在 CLI shell 提供",
            "passed": False,
        },
        {
            "key": "postwrite_evidence_saved",
            "label": "正式寫入後必須保存 writer output 與 post-write smoke 結果",
            "passed": False,
        },
    ]


def build_candidate_queue_writer_run_package(
    *,
    transaction_preview,
    writer_preflight,
    writer_status,
    postwrite_smoke,
    operator_drill,
):
    """建立正式 operator run package preview；不執行任何副作用。"""
    payloads = _statement_payloads(transaction_preview)
    payload_manifest_hash = _stable_hash(payloads)
    gates = _package_gates(
        transaction_preview=transaction_preview,
        writer_preflight=writer_preflight,
        writer_status=writer_status,
        postwrite_smoke=postwrite_smoke,
        operator_drill=operator_drill,
    )
    blocked_reasons = [gate["key"] for gate in gates if not gate["passed"]]
    package_ready = bool(payloads and operator_drill.get("operator_drill_ready"))

    return {
        "mode": "candidate_queue_writer_run_package_preview",
        "target_table": "market_alert_review_queue",
        "package_ready": package_ready,
        "package_artifact_created": False,
        "api_writes_file": False,
        "api_executes_cli": False,
        "api_reads_approval_token": False,
        "api_writes_database": False,
        "database_connection_opened": False,
        "database_session_created": False,
        "explicit_transaction_opened": False,
        "database_write_executed": False,
        "database_commit_executed": False,
        "database_rollback_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "writes_executed": False,
        "would_write_database": False,
        "blocked_reasons": blocked_reasons,
        "payload_manifest": {
            "payload_count": len(payloads),
            "manifest_hash": payload_manifest_hash,
            "dedupe_keys": [
                item["dedupe_key"] for item in payloads if item.get("dedupe_key")
            ],
            "payloads": payloads,
            "redaction_policy": [
                "do_not_include_approval_token",
                "do_not_include_raw_html",
                "do_not_include_login_or_member_data",
            ],
        },
        "required_artifacts": [
            {
                "key": "reviewed_sample_json",
                "label": "操作員保存的真實 reviewed sample JSON",
                "path_shape": "artifacts/market_intel/reviewed-sample-YYYYMMDD-HHMMSS.json",
                "created_by_api": False,
            },
            {
                "key": "project_backup_zip",
                "label": "正式寫入前備份檔",
                "path_shape": "scripts/tools/backups/momo_pro_system_backup_*.zip",
                "created_by_api": False,
            },
            {
                "key": "read_only_preflight_json",
                "label": "CLI read-only preflight 輸出",
                "path_shape": "artifacts/market_intel/preflight-*.json",
                "created_by_api": False,
            },
            {
                "key": "writer_output_json",
                "label": "CLI writer 正式執行輸出",
                "path_shape": "artifacts/market_intel/writer-output-*.json",
                "created_by_api": False,
            },
            {
                "key": "postwrite_smoke_json",
                "label": "post-write smoke 只讀驗證輸出",
                "path_shape": "artifacts/market_intel/postwrite-smoke-*.json",
                "created_by_api": False,
            },
        ],
        "command_bundle": [
            {
                "step": 1,
                "key": "save_reviewed_sample",
                "command_shape": (
                    "mkdir -p artifacts/market_intel && "
                    "write reviewed sample JSON to artifacts/market_intel/"
                    "reviewed-sample-YYYYMMDD-HHMMSS.json"
                ),
                "executes_database": False,
            },
            {
                "step": 2,
                "key": "backup",
                "command_shape": "python3 scripts/tools/backup_system.py",
                "executes_database": False,
            },
            {
                "step": 3,
                "key": "preflight",
                "command_shape": (
                    "python3 scripts/market_intel_candidate_queue_writer.py "
                    "--sample-json artifacts/market_intel/reviewed-sample.json "
                    "--read-only-preflight > artifacts/market_intel/preflight.json"
                ),
                "executes_database": False,
            },
            {
                "step": 4,
                "key": "writer",
                "command_shape": (
                    "MARKET_INTEL_QUEUE_WRITE_APPROVAL=... "
                    "python3 scripts/market_intel_candidate_queue_writer.py "
                    "--sample-json artifacts/market_intel/reviewed-sample.json "
                    "--read-only-preflight --backup-verified "
                    "--migration-live-smoke-passed --execute --apply-real-write "
                    "--approval-token \"$MARKET_INTEL_QUEUE_WRITE_APPROVAL\" "
                    "> artifacts/market_intel/writer-output.json"
                ),
                "executes_database": True,
            },
            {
                "step": 5,
                "key": "postwrite_smoke",
                "command_shape": (
                    "POST /api/market_intel/manual_sample_review/"
                    "candidate_queue_writer_postwrite_smoke?execute=true "
                    "> artifacts/market_intel/postwrite-smoke.json"
                ),
                "executes_database": False,
            },
        ],
        "operator_signoff": [
            "確認 reviewed sample JSON 來自真實公開頁抓取結果",
            "確認備份檔路徑與時間",
            "確認 migration live smoke 結果為通過或可接受狀態",
            "確認 writer output 的 inserted_count / skipped_count",
            "確認 post-write smoke 找到預期 dedupe key",
        ],
        "rollback_plan": [
            {
                "key": "no_preview_side_effect",
                "label": "此 run package preview 沒有副作用，不需要 DB rollback",
            },
            {
                "key": "dedupe_key_cleanup_review",
                "label": "正式 CLI 寫入後若需回退，依 dedupe key 人工審核清理",
            },
            {
                "key": "keep_market_flags_disabled",
                "label": "異常時維持 MARKET_INTEL_* flags 關閉，不掛 scheduler",
            },
        ],
        "safe_boundaries": [
            "do_not_create_run_artifacts_from_api",
            "do_not_execute_cli_from_api",
            "do_not_read_approval_token_from_api",
            "do_not_open_database_connection_from_run_package_preview",
            "do_not_write_queue_from_run_package_preview",
            "do_not_attach_scheduler_from_run_package",
            "no_remove_orphans",
            "no_momo_db_lifecycle_change",
        ],
    }
