// Package genexchain — Compliance Ante Handler Integration
//
// 本文件将独立的 ComplianceAnteHandler (x/evm/ante/) 桥接到
// Cosmos SDK ante handler 链中，实现验证节点级交易拦截。
//
// 对应指南: 06-区块链开发指南.md §6 (链级合规能力) 和 §16 (验证节点级交易拦截)
//
// 架构:
//
//	TX → ComplianceAnteWrapper (OFAC/TravelRule/Structuring)
//	   → cosmos/evm AnteHandler (签名/Gas/Nonce/...)
//	   → Mempool → Block
//
// ComplianceAnteHandler 执行三项检查:
//  1. OFAC 地址拦截 — 制裁名单地址的交易直接拒绝，不进入 mempool
//  2. Structuring 检测 — 24h 内拆分交易规避 $3,000 阈值，标记为可疑
//  3. Travel Rule 预打包检查 — ≥$3,000 转移必须已记录身份哈希
//
// OFAC 名单由链下合规服务通过 ComplianceHandler.UpdateOFACList() 定期同步。
// Travel Rule 数据由 compliance-service 通过 ComplianceHandler.RecordTravelRule() 写入。
package genexchain

import (
	"fmt"
	"math/big"

	sdk "github.com/cosmos/cosmos-sdk/types"
	evmtypes "github.com/cosmos/evm/x/vm/types"
	"github.com/ethereum/go-ethereum/common"

	genexante "github.com/genex/genex-chain/x/evm/ante"
)

// ComplianceAnteWrapper 将独立的 ComplianceAnteHandler 桥接到 Cosmos SDK ante 链。
//
// 工作流程:
//  1. 遍历 tx 中的所有消息
//  2. 对 MsgEthereumTx 类型的消息提取 from/to/value
//  3. 调用 ComplianceAnteHandler.AnteHandle() 执行合规检查
//  4. 如果被拒绝 → 返回错误，交易不会被打包
//  5. 如果可疑 → 记录日志，交易仍可打包
//  6. 记录转移金额用于 Structuring 滑动窗口检测
//  7. 合规通过后委托给标准 cosmos/evm ante handler
type ComplianceAnteWrapper struct {
	compliance *genexante.ComplianceAnteHandler
	inner      sdk.AnteHandler
}

// NewComplianceAnteWrapper 创建包含合规检查的 ante handler。
//
// 参数:
//   - inner: 标准 cosmos/evm ante handler (由 evmante.NewAnteHandler 创建)
//   - compliance: Genex 合规检查处理器
//
// 用法 (在 app.go 中):
//
//	standardHandler := evmante.NewAnteHandler(options)
//	complianceHandler := genexante.NewComplianceAnteHandler()
//	wrappedHandler := NewComplianceAnteWrapper(standardHandler, complianceHandler)
//	app.SetAnteHandler(wrappedHandler)
func NewComplianceAnteWrapper(
	inner sdk.AnteHandler,
	compliance *genexante.ComplianceAnteHandler,
) sdk.AnteHandler {
	w := &ComplianceAnteWrapper{
		compliance: compliance,
		inner:      inner,
	}
	return w.AnteHandle
}

// AnteHandle 在标准 ante handler 之前执行合规检查。
//
// 对于非 EVM 的 Cosmos SDK 消息（如 staking、gov），合规检查被跳过，
// 直接委托给内部 handler。
//
// 模拟模式 (simulate=true) 下跳过合规检查，因为 gas 估算不应被合规拒绝。
func (w *ComplianceAnteWrapper) AnteHandle(
	ctx sdk.Context, tx sdk.Tx, simulate bool,
) (sdk.Context, error) {
	// 模拟模式跳过合规检查（gas 估算）
	if simulate {
		return w.inner(ctx, tx, simulate)
	}

	for _, msg := range tx.GetMsgs() {
		// 仅拦截 EVM 交易；Cosmos 原生消息直接放行
		ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
		if !ok {
			continue
		}

		// 获取底层 go-ethereum Transaction 对象
		ethTx := ethMsg.AsTransaction()
		if ethTx == nil {
			continue
		}

		// 提取发送方 (from) — Cosmos AccAddress bytes → Ethereum hex
		fromBytes := ethMsg.GetFrom()
		fromAddr := common.BytesToAddress(fromBytes)

		// 提取接收方 (to) — 合约创建时为 nil
		toHex := ""
		if ethTx.To() != nil {
			toHex = ethTx.To().Hex()
		}

		// 提取交易金额
		value := ethTx.Value()
		if value == nil {
			value = new(big.Int)
		}

		// ====== 执行合规检查 ======
		result := w.compliance.AnteHandle(fromAddr.Hex(), toHex, value)

		// 检查 1: OFAC / Travel Rule 拒绝 → 交易不进入 mempool
		if !result.Allowed {
			ctx.Logger().Error("Transaction rejected by compliance",
				"module", "genex-compliance",
				"from", fromAddr.Hex(),
				"to", toHex,
				"value", value.String(),
				"reason", result.Reason,
			)
			return ctx, fmt.Errorf("genex compliance: %s", result.Reason)
		}

		// 检查 2: 可疑但允许 → 记录警告日志，交易仍可打包
		if result.Suspicious {
			ctx.Logger().Warn("Suspicious transaction detected",
				"module", "genex-compliance",
				"from", fromAddr.Hex(),
				"to", toHex,
				"value", value.String(),
				"reason", result.SuspReason,
			)
		}

		// 检查 3: 记录转移金额用于 Structuring 滑动窗口检测
		if value.Sign() > 0 {
			w.compliance.RecordTransfer(fromAddr.Hex(), value)
		}
	}

	// 合规通过，委托给标准 cosmos/evm ante handler
	return w.inner(ctx, tx, simulate)
}
