"""Gate checks for review decision approval writer preflight."""

from services.market_intel.mcp_fetch_candidate_queue_writer_preflight import TARGET_TABLE
from services.market_intel.mcp_fetch_candidate_queue_writer_review_decision_gates import (
    ALLOWED_REVIEW_DECISIONS,
)

ALLOWED_PREFLIGHT_MODES = ("cli_only_writer_preflight_preview",)
ALLOWED_PREFLIGHT_SCOPES = (
    "candidate_queue_review_decision_approval_writer_preflight",
)
TARGET_OPERATION = "update_review_state_from_approved_decision"


def _row_keys_match_expected(preflight):
    row_keys = [row["dedupe_key"] for row in preflight["preflight_rows"]]
    expected_keys = preflight["expected_dedupe_keys"]
    return bool(
        row_keys
        and len(row_keys) == len(set(row_keys))
        and set(row_keys) == set(expected_keys)
    )


def _preflight_rows_match_approval(approval, preflight):
    approval_rows = {
        row["dedupe_key"]: row for row in approval["approval_rows"]
    }
    if not approval_rows or not preflight["preflight_rows"]:
        return False
    for row in preflight["preflight_rows"]:
        source = approval_rows.get(row["dedupe_key"])
        if not source:
            return False
        if row["current_review_state"] != source["current_review_state"]:
            return False
        if row["approved_review_decision"] != source["approved_review_decision"]:
            return False
        if row["target_review_state"] != source["approved_review_decision"]:
            return False
        if row["decision_evidence_ref"] != source["decision_evidence_ref"]:
            return False
        if row["approval_evidence_ref"] != source["approval_evidence_ref"]:
            return False
    return True


def _all_rows_have_allowed_transitions(preflight):
    return bool(
        preflight["preflight_rows"]
        and all(
            row["current_review_state"] == "needs_review"
            and row["approved_review_decision"] in ALLOWED_REVIEW_DECISIONS
            and row["target_review_state"] in ALLOWED_REVIEW_DECISIONS
            and row["approved_review_decision"] == row["target_review_state"]
            and row["statement_type"] == "update_review_state"
            and row["operation"] == "update"
            for row in preflight["preflight_rows"]
        )
    )


def _all_rows_have_preflight_evidence(preflight):
    return bool(
        preflight["preflight_rows"]
        and all(
            row["preflight_notes_present"]
            and row["decision_evidence_ref_safe"]
            and row["approval_evidence_ref_safe"]
            and row["preflight_evidence_ref_safe"]
            for row in preflight["preflight_rows"]
        )
    )


def _matched_rows_keep_identity_guards(preflight):
    matched_rows = [
        row
        for row in preflight["preflight_rows"]
        if row["target_review_state"] == "matched"
    ]
    if not matched_rows:
        return True
    return all(
        row["evidence_lane"] == "exact_identity"
        and row["exact_identity_confirmed"]
        and not row["hard_veto_present"]
        and not row["stronger_existing_match_conflict"]
        and row["false_positive_guard_passed"]
        and row["variant_conflict_checked"]
        and row["overwrite_protection_checked"]
        for row in matched_rows
    )


def build_approval_writer_preflight_gates(
    *, approval_received, preflight_received, approval, preflight
):
    operator_confirmed_boundaries = bool(
        preflight["approval_checked"]
        and preflight["writer_preflight_is_cli_only"]
        and preflight["manual_record_required"]
        and preflight["no_approval_token_payload"]
        and preflight["no_api_cli_execution"]
        and preflight["no_api_database_write"]
        and preflight["no_api_review_state_update"]
        and preflight["no_api_decision_record_write"]
        and preflight["no_api_match_write"]
        and preflight["no_api_queue_insert"]
        and preflight["no_api_file_write"]
        and preflight["no_scheduler_attach"]
        and preflight["rows_match_approval"]
        and preflight["schema_preflight_required"]
        and preflight["status_transition_reviewed"]
        and preflight["stronger_existing_match_guard_preserved"]
        and preflight["false_positive_guard_completed"]
        and preflight["variant_sensitive_review_completed"]
        and preflight["hard_veto_respected"]
    )
    return [
        {
            "key": "candidate_queue_review_decision_approval_payload_or_result_received",
            "label": "已提供 review decision approval package 或已審核結果",
            "passed": approval_received,
        },
        {
            "key": "candidate_queue_review_decision_approval_accepted",
            "label": "review decision approval gate 必須已通過",
            "passed": approval["accepted"],
        },
        {
            "key": "candidate_queue_review_decision_approval_ready_for_preflight",
            "label": "approval 必須只放行到 writer preflight",
            "passed": approval["ready_for_candidate_queue_review_decision_writer_preflight"],
        },
        {
            "key": "candidate_queue_review_decision_approval_side_effect_free",
            "label": "approval 未顯示 API 寫 DB、寫 approval、寫 decision、寫 match 或更新 review_state",
            "passed": approval["side_effects_clear"],
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_payload_received",
            "label": "已提供 operator writer preflight 摘要",
            "passed": preflight_received,
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_identity_recorded",
            "label": "writer preflight 必須記錄 preflight_id 與上游 identity",
            "passed": bool(
                preflight["writer_preflight_id"]
                and preflight["approval_id"]
                and preflight["review_decision_id"]
                and preflight["review_inventory_id"]
                and preflight["handoff_id"]
                and preflight["inventory_review_id"]
                and preflight["closeout_id"]
                and preflight["run_package_id"]
                and preflight["receipt_id"]
            ),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_identity_matches_approval",
            "label": "writer preflight identity 必須對齊 approval",
            "passed": bool(
                preflight["approval_id"] == approval["approval_id"]
                and preflight["review_decision_id"] == approval["review_decision_id"]
                and preflight["review_inventory_id"] == approval["review_inventory_id"]
                and preflight["handoff_id"] == approval["handoff_id"]
                and preflight["inventory_review_id"] == approval["inventory_review_id"]
                and preflight["closeout_id"] == approval["closeout_id"]
                and preflight["run_package_id"] == approval["run_package_id"]
                and preflight["receipt_id"] == approval["receipt_id"]
            ),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_target_table_safe",
            "label": "target table 必須是 market_alert_review_queue",
            "passed": preflight["target_table"] == TARGET_TABLE,
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_scope_safe",
            "label": "writer preflight 僅能是 CLI-only preview",
            "passed": bool(
                preflight["preflight_scope"] in ALLOWED_PREFLIGHT_SCOPES
                and preflight["preflight_mode"] in ALLOWED_PREFLIGHT_MODES
                and preflight["target_operation"] == TARGET_OPERATION
                and preflight["expected_current_review_state"] == "needs_review"
            ),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_row_count_matches_approval",
            "label": "writer preflight row count 必須對齊 approval row count",
            "passed": bool(
                preflight["expected_preflight_row_count"]
                and preflight["preflight_row_count"]
                == preflight["expected_preflight_row_count"]
                == approval["approved_row_count"]
                and len(preflight["preflight_rows"]) == approval["approved_row_count"]
            ),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_rows_match_approval",
            "label": "writer preflight rows 必須逐列對齊 approval rows",
            "passed": bool(
                _row_keys_match_expected(preflight)
                and _preflight_rows_match_approval(approval, preflight)
            ),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_transitions_allowed",
            "label": "writer preflight 只能產生允許的 review_state update preview",
            "passed": _all_rows_have_allowed_transitions(preflight),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_row_evidence_complete",
            "label": "每列 writer preflight 必須保留 decision、approval 與 preflight evidence",
            "passed": _all_rows_have_preflight_evidence(preflight),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_matched_rows_keep_identity_guards",
            "label": "matched preflight rows 必須保留 exact identity、variant 與 overwrite guard",
            "passed": _matched_rows_keep_identity_guards(preflight),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_artifact_paths_safe",
            "label": "review queue、inventory、decision、approval 與 preflight artifact paths 必須安全並對齊",
            "passed": bool(
                preflight["review_queue_artifact_path_safe"]
                and preflight["review_inventory_artifact_path_safe"]
                and preflight["review_decision_artifact_path_safe"]
                and preflight["approval_artifact_path_safe"]
                and preflight["writer_preflight_artifact_path_safe"]
                and preflight["review_queue_artifact_path"]
                == approval["review_queue_artifact_path"]
                and preflight["review_inventory_artifact_path"]
                == approval["review_inventory_artifact_path"]
                and preflight["review_decision_artifact_path"]
                == approval["review_decision_artifact_path"]
                and preflight["approval_artifact_path"]
                == approval["approval_artifact_path"]
            ),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_operator_boundaries_confirmed",
            "label": "操作員確認 API 未執行 CLI/DB/file/review_state/decision/match/scheduler",
            "passed": operator_confirmed_boundaries,
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_no_api_execution_or_real_write",
            "label": "writer preflight payload 不得允許 API execution、real write、review update、decision write 或 match write",
            "passed": bool(
                not preflight["api_execution_allowed"]
                and not preflight["real_write_allowed_by_api"]
                and not preflight["api_candidate_review_allowed"]
                and not preflight["api_updates_review_state"]
                and not preflight["api_writes_preflight_record"]
                and not preflight["api_writes_approval_record"]
                and not preflight["api_writes_decision_record"]
                and not preflight["api_writes_match_result"]
            ),
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_no_secret_or_token_key",
            "label": "writer preflight payload 不得包含 secret、cookie、password 或 token key",
            "passed": not preflight["secret_or_token_submitted_to_api"],
        },
        {
            "key": "candidate_queue_review_decision_approval_writer_preflight_side_effect_free",
            "label": "writer preflight payload 不得要求 API 寫檔、執行、寫 DB、補 queue、寫 match 或掛 scheduler",
            "passed": not preflight["blocked_side_effects"],
        },
    ]
