"""审批与幂等的顺序内存模拟：无真实付款、认证、事务或持久化。"""
from dataclasses import asdict, dataclass
import hashlib
import json


@dataclass(frozen=True)
class Draft:
    tenant: str
    user: str
    operation_id: str
    order_id: str
    amount_minor: int
    currency: str = "CNY"
    revision: int = 1


def fingerprint(draft: Draft) -> str:
    # 参数、主体、操作与版本共同绑定；哈希只是比对方法，不是授权凭证。
    content = json.dumps(asdict(draft), sort_keys=True, separators=(",", ":"))
    return hashlib.sha256(content.encode()).hexdigest()


def parse_decision(payload: dict) -> bool:
    if not isinstance(payload, dict) or set(payload) != {"approved"}:
        raise ValueError("invalid_approval_fields")
    if type(payload["approved"]) is not bool:
        raise ValueError("approved_must_be_boolean")
    return payload["approved"]


@dataclass(frozen=True)
class Approval:
    digest: str
    approved: bool
    expires_at: float


def approve(draft: Draft, decision: dict, now: float) -> Approval:
    # 调用者代表可信审批通道。生产还需要验证批准者身份、角色与 CSRF 等边界。
    return Approval(fingerprint(draft), parse_decision(decision), now + 600)


class Ledger:
    def __init__(self) -> None:
        # 主体范围与操作 ID 共同作键，支持同一订单的不同合法操作。
        self.rows: dict[tuple[str, str, str], tuple[str, dict]] = {}

    def submit(self, draft: Draft, approval: Approval, *, now: float,
               authorized: bool, eligible: bool) -> dict:
        if not authorized:
            raise ValueError("permission_denied")
        if type(draft.amount_minor) is not int or draft.amount_minor <= 0:
            raise ValueError("invalid_amount")
        if draft.currency != "CNY":
            raise ValueError("unsupported_demo_currency")
        digest = fingerprint(draft)
        if not approval.approved or approval.digest != digest or now >= approval.expires_at:
            raise ValueError("approval_invalid_or_expired")
        key = (draft.tenant, draft.user, draft.operation_id)
        if key in self.rows:
            saved_digest, result = self.rows[key]
            if saved_digest != digest:
                raise ValueError("idempotency_conflict")
            return dict(result)  # 同一意图返回既有结果，不再产生新效果。
        if not eligible:
            raise ValueError("business_preconditions_not_met")
        # 只生成模拟回执；正式服务要结合唯一约束、下游幂等与结果对账。
        result = {"status": "simulated_submitted", "operation_id": draft.operation_id,
                  "amount_minor": draft.amount_minor, "currency": draft.currency}
        self.rows[key] = (digest, result)
        return dict(result)

    def lookup(self, tenant: str, user: str, operation_id: str) -> dict | None:
        # 这里假定 tenant/user 已经过可信授权；生产读取回执也需检查归属。
        row = self.rows.get((tenant, user, operation_id))
        return dict(row[1]) if row else None


if __name__ == "__main__":
    draft = Draft("shop-a", "user-417", "refund-op-9", "A1042", 10000)
    approval = approve(draft, {"approved": True}, now=0)
    ledger = Ledger()
    # eligible=True 为人工模拟审核完成，不是从“用户说质量有问题”推导出来。
    print(ledger.submit(draft, approval, now=1, authorized=True, eligible=True))
    print(ledger.submit(draft, approval, now=2, authorized=True, eligible=True))
