import mizan  # mizan-sdk: verify_token is offline when keys are given

TYPE = "market.mizan.verdict"   # AP2 Mandate Constraint type (carriage for AP2 v0.2 Payment Mandates)


def ap2_verdict_ok(constraint, payment_mandate, token, keys, now=None):
    """constraint: {"type": TYPE, "rule": "sha256:..."}, user-signed in the OPEN Payment Mandate. payment_mandate: the CLOSED
    Payment Mandate contents (payee {id, website}). token: the mzv1 verdict presented with it. keys: your pinned
    {kid: base64 Ed25519}. Offline. -> (ok, code). Per AP2, a verifier without this constraint type fails it (unresolved)."""
    if (constraint or {}).get("type") != TYPE or not str(constraint.get("rule") or "").startswith("sha256:"):
        return False, "unresolved_constraint"
    r = mizan.verify_token(token or "", keys, rule=constraint["rule"], now=now)
    if not r["ok"]:
        return False, r["code"]
    c, p = r["claims"], (payment_mandate or {}).get("payee") or {}
    norm = lambda s: str(s or "").strip().lower() if str(s or "").strip().lower().startswith("0x") else str(s or "").strip()  # noqa: E731
    bt = c.get("bound_to") or {}
    if not bt or norm(bt.get("payee")) not in {norm(p.get("id")), norm(p.get("website"))} - {""}:
        return False, "payee_mismatch"
    if bt.get("rule") != constraint["rule"]:
        return False, "rule_mismatch"
    return (True, "valid") if c.get("decision") == "ALLOW" else (False, "refused")
