// Package ports defines wallet-service usecase dependencies.
package ports

import (
	"context"
	"time"

	"hyapp/pkg/walletmq"
	"hyapp/services/wallet-service/internal/domain/ledger"
	resourcedomain "hyapp/services/wallet-service/internal/domain/resource"
)

// Repository 聚合 wallet-service 当前运行需要的全部持久化能力。
//
// 门面层继续接收这个总接口，usecase 拆分时按下方能力接口依赖最小端口，避免单测
// 为一个用例实现完整钱包仓储面。
type Repository interface {
	GiftLedgerStore
	BalanceStore
	HostSalaryStore
	CoinSellerStore
	AdminLedgerStore
	RewardLedgerStore
	GameLedgerStore
	RechargeStore
	ExternalRechargeStore
	VIPStore
	RedPacketStore
	ResourceCatalogStore
	ResourceGrantStore
	ResourceEquipmentStore
	ResourceShopStore
	WalletProjectionStore
	BadgeProjectionStore
}

// GiftLedgerStore 管理礼物扣费；repository 必须保证余额、幂等交易和 outbox 同事务提交。
type GiftLedgerStore interface {
	DebitGift(ctx context.Context, command ledger.DebitGiftCommand) (ledger.Receipt, error)
	BatchDebitGift(ctx context.Context, command ledger.BatchDebitGiftCommand) (ledger.BatchGiftReceipt, error)
}

// BalanceStore 提供钱包余额、首页、流水和礼物墙读模型。
type BalanceStore interface {
	GetBalances(ctx context.Context, userID int64, assetTypes []string) ([]ledger.AssetBalance, error)
	GetWalletOverview(ctx context.Context, userID int64) (ledger.WalletOverview, error)
	GetWalletValueSummary(ctx context.Context, userID int64) (ledger.WalletValueSummary, error)
	GetUserGiftWall(ctx context.Context, userID int64) (ledger.UserGiftWall, error)
	GetDiamondExchangeConfig(ctx context.Context, userID int64) ([]ledger.DiamondExchangeRule, error)
	ListWalletTransactions(ctx context.Context, query ledger.ListWalletTransactionsQuery) ([]ledger.WalletTransaction, int64, error)
	ListHostPeriodDiamondTransactions(ctx context.Context, query ledger.ListWalletTransactionsQuery) ([]ledger.WalletTransaction, int64, error)
}

// HostSalaryStore 管理主播/公会工资政策、进度和批量结算。
type HostSalaryStore interface {
	GetActiveHostSalaryPolicy(ctx context.Context, regionID int64, settlementMode string, triggerMode string, cycleKey string) (ledger.HostSalaryPolicy, bool, error)
	GetHostSalaryProgress(ctx context.Context, userID int64, cycleKey string) (ledger.HostSalaryProgress, error)
	GetTeamHostSalaryStats(ctx context.Context, query ledger.TeamHostSalaryStatsQuery) ([]ledger.TeamHostSalaryCycleStat, error)
	GetHostRevenueStats(ctx context.Context, query ledger.HostRevenueStatsQuery) (ledger.HostRevenueStats, error)
	GetAgencyHostGiftStats(ctx context.Context, query ledger.AgencyHostGiftStatsQuery) (ledger.AgencyHostGiftStats, error)
	ProcessHostSalarySettlementBatch(ctx context.Context, command ledger.HostSalarySettlementBatchCommand) (ledger.HostSalarySettlementBatchResult, error)
}

// CoinSellerStore 管理币商库存、转币和工资换币。
type CoinSellerStore interface {
	AdminCreditCoinSellerStock(ctx context.Context, command ledger.CoinSellerStockCreditCommand) (ledger.CoinSellerStockCreditReceipt, error)
	TransferCoinFromSeller(ctx context.Context, command ledger.CoinSellerTransferCommand) (ledger.CoinSellerTransferReceipt, error)
	TransferCoinSellerStockToChild(ctx context.Context, command ledger.CoinSellerSubTransferCommand) (ledger.CoinSellerSubTransferReceipt, error)
	ListCoinSellerSalaryExchangeRateTiers(ctx context.Context, appCode string, regionID int64, includeDisabled bool) ([]ledger.CoinSellerSalaryExchangeRateTier, error)
	ExchangeSalaryToCoin(ctx context.Context, command ledger.SalaryExchangeCommand) (ledger.SalaryExchangeReceipt, error)
	TransferSalaryToCoinSeller(ctx context.Context, command ledger.SalaryTransferToCoinSellerCommand) (ledger.SalaryTransferToCoinSellerReceipt, error)
	ListPointWithdrawalCoinSellers(ctx context.Context, appCode string, regionID int64, countryCode string, includeDisabled bool) ([]ledger.PointWithdrawalCoinSellerConfig, error)
	TransferPointToCoinSeller(ctx context.Context, command ledger.PointToCoinSellerCommand) (ledger.PointToCoinSellerReceipt, error)
	ExchangePointToCoin(ctx context.Context, command ledger.PointToCoinCommand) (ledger.PointToCoinReceipt, error)
	GetPointWithdrawalConfig(ctx context.Context, appCode string, regionID int64, nowMS int64) (ledger.PointWithdrawalRuntimeConfig, error)
	GetPointWithdrawalConfigForAsset(ctx context.Context, appCode string, regionID int64, nowMS int64, assetType string) (ledger.PointWithdrawalRuntimeConfig, error)
	GetPointWithdrawalConfigForUser(ctx context.Context, appCode string, userID int64, regionID int64, nowMS int64, assetType string) (ledger.PointWithdrawalRuntimeConfig, error)
	FreezeSalaryWithdrawal(ctx context.Context, command ledger.SalaryWithdrawalCommand) (ledger.SalaryWithdrawalReceipt, error)
	SettleSalaryWithdrawal(ctx context.Context, command ledger.SalaryWithdrawalCommand) (ledger.SalaryWithdrawalReceipt, error)
	ReleaseSalaryWithdrawal(ctx context.Context, command ledger.SalaryWithdrawalCommand) (ledger.SalaryWithdrawalReceipt, error)
}

// AdminLedgerStore 管理后台人工调账。
type AdminLedgerStore interface {
	AdminCreditAsset(ctx context.Context, command ledger.AdminCreditAssetCommand) (ledger.AssetBalance, string, error)
}

// RewardLedgerStore 管理活动和运营奖励入账。
type RewardLedgerStore interface {
	CreditTaskReward(ctx context.Context, command ledger.TaskRewardCommand) (ledger.TaskRewardReceipt, error)
	CreditLuckyGiftReward(ctx context.Context, command ledger.LuckyGiftRewardCommand) (ledger.LuckyGiftRewardReceipt, error)
	CreditWheelReward(ctx context.Context, command ledger.WheelRewardCommand) (ledger.WheelRewardReceipt, error)
	CreditRoomTurnoverReward(ctx context.Context, command ledger.RoomTurnoverRewardCommand) (ledger.RoomTurnoverRewardReceipt, error)
	CreditInviteActivityReward(ctx context.Context, command ledger.InviteActivityRewardCommand) (ledger.InviteActivityRewardReceipt, error)
	CreditAgencyOpeningReward(ctx context.Context, command ledger.AgencyOpeningRewardCommand) (ledger.AgencyOpeningRewardReceipt, error)
	DebitWheelDraw(ctx context.Context, command ledger.WheelDrawDebitCommand) (ledger.WheelDrawDebitReceipt, error)
	DebitCPBreakupFee(ctx context.Context, command ledger.CPBreakupFeeCommand) (ledger.CPBreakupFeeReceipt, error)
}

// GameLedgerStore 管理游戏扣款、返奖、退款和冲正账变。
type GameLedgerStore interface {
	ApplyGameCoinChange(ctx context.Context, command ledger.GameCoinChangeCommand) (ledger.GameCoinChangeReceipt, error)
}

// RechargeStore 管理内购充值档位、Google 支付和充值账单。
type RechargeStore interface {
	ListRechargeBills(ctx context.Context, query ledger.ListRechargeBillsQuery) ([]ledger.RechargeBill, int64, error)
	SummarizeRechargeBills(ctx context.Context, query ledger.ListRechargeBillsQuery) (ledger.RechargeBillSummary, error)
	BatchGetUserRechargeStats(ctx context.Context, userIDs []int64) ([]ledger.UserRechargeStats, error)
	GetRechargeBillOverview(ctx context.Context, query ledger.ListRechargeBillsQuery, tzOffsetMinutes int32) (ledger.RechargeBillOverview, error)
	ListGooglePaymentOrderRefs(ctx context.Context, appCode string, transactionIDs []string) (map[string]ledger.GooglePaymentOrderRef, error)
	ListPendingGooglePaymentOrderRefs(ctx context.Context, limit int, nowMS int64) ([]ledger.GooglePaymentOrderRef, error)
	UpdateGooglePaymentPaidDetails(ctx context.Context, appCode string, paymentOrderID string, details ledger.GooglePaymentPaidDetails) error
	MarkGooglePaymentPaidSyncFailure(ctx context.Context, ref ledger.GooglePaymentOrderRef, message string, nowMS int64) error
	ListRechargeProducts(ctx context.Context, userID int64, regionID int64, platform string, audienceType string) ([]ledger.RechargeProduct, []string, error)
	ListAdminRechargeProducts(ctx context.Context, query ledger.ListRechargeProductsQuery) ([]ledger.RechargeProduct, int64, error)
	GetRechargeProduct(ctx context.Context, appCode string, productID int64) (ledger.RechargeProduct, error)
	GetGoogleRechargeProductByCode(ctx context.Context, appCode string, googleProductID string) (ledger.RechargeProduct, error)
	ConfirmGooglePayment(ctx context.Context, command ledger.GooglePaymentCommand, product ledger.RechargeProduct, purchase ledger.GooglePlayPurchase) (ledger.GooglePaymentReceipt, error)
	MarkGooglePaymentConsumed(ctx context.Context, appCode string, paymentOrderID string) error
	CreateRechargeProduct(ctx context.Context, command ledger.RechargeProductCommand) (ledger.RechargeProduct, error)
	UpdateRechargeProduct(ctx context.Context, command ledger.RechargeProductCommand) (ledger.RechargeProduct, error)
	DeleteRechargeProduct(ctx context.Context, appCode string, productID int64) error
}

// ExternalRechargeStore 管理 H5 三方充值方式、订单、回调和查单补偿。
type ExternalRechargeStore interface {
	ListThirdPartyPaymentChannels(ctx context.Context, query ledger.ListThirdPartyPaymentChannelsQuery) ([]ledger.ThirdPartyPaymentChannel, error)
	SetThirdPartyPaymentMethodStatus(ctx context.Context, command ledger.ThirdPartyPaymentMethodStatusCommand) (ledger.ThirdPartyPaymentMethod, error)
	UpdateThirdPartyPaymentRate(ctx context.Context, command ledger.ThirdPartyPaymentRateCommand) (ledger.ThirdPartyPaymentMethod, error)
	UpsertThirdPartyPaymentMethods(ctx context.Context, appCode string, providerCode string, methods []ledger.ThirdPartyPaymentMethod) (int, int, error)
	GetThirdPartyPaymentMethod(ctx context.Context, appCode string, methodID int64) (ledger.ThirdPartyPaymentMethod, error)
	ListH5RechargeOptions(ctx context.Context, query ledger.H5RechargeOptionsQuery) (ledger.H5RechargeOptions, error)
	ListTemporaryExternalRechargeOrders(ctx context.Context, query ledger.ListTemporaryExternalRechargeOrdersQuery) ([]ledger.ExternalRechargeOrder, int64, error)
	CreateExternalRechargeOrder(ctx context.Context, command ledger.CreateExternalRechargeOrderCommand, product ledger.RechargeProduct, method *ledger.ThirdPartyPaymentMethod, providerAmountMinor int64, receiveAddress string) (ledger.ExternalRechargeOrder, error)
	CreateTemporaryExternalRechargeOrder(ctx context.Context, command ledger.CreateTemporaryExternalRechargeOrderCommand, method ledger.ThirdPartyPaymentMethod, providerAmountMinor int64) (ledger.ExternalRechargeOrder, error)
	MarkExternalRechargeOrderRedirected(ctx context.Context, appCode string, orderID string, providerOrderID string, payURL string, payloadJSON string) (ledger.ExternalRechargeOrder, error)
	AttachExternalRechargeTx(ctx context.Context, command ledger.SubmitExternalRechargeTxCommand, payloadJSON string) (ledger.ExternalRechargeOrder, error)
	CreditExternalRechargeOrder(ctx context.Context, appCode string, orderID string, providerOrderID string, txHash string, payloadJSON string) (ledger.ExternalRechargeOrder, error)
	MarkExternalRechargeOrderPaid(ctx context.Context, appCode string, orderID string, providerOrderID string, payloadJSON string) (ledger.ExternalRechargeOrder, error)
	MarkExternalRechargeOrderFailed(ctx context.Context, appCode string, orderID string, reason string, payloadJSON string) (ledger.ExternalRechargeOrder, error)
	GetExternalRechargeOrder(ctx context.Context, appCode string, orderID string) (ledger.ExternalRechargeOrder, error)
	ListExternalRechargeOrdersForReconcile(ctx context.Context, appCode string, limit int) ([]ledger.ExternalRechargeOrder, error)
}

// VIPStore 管理 VIP 购买、发放、每日返现和后台等级配置。
type VIPStore interface {
	// ListVipPackages 在同一个数据库快照中返回最终 VIP 状态和套餐，避免配置切换时拼出跨版本响应。
	ListVipPackages(ctx context.Context, userID int64) (ledger.VipState, []ledger.VipLevel, error)
	GetMyVip(ctx context.Context, userID int64) (ledger.UserVip, error)
	// GetVipProgramConfig 返回单 App 的显式状态机和权益目录，调用方不得按 app_code 复制规则分支。
	GetVipProgramConfig(ctx context.Context) (ledger.VipProgramConfig, []ledger.VipBenefit, error)
	// GetVipState 是 paid membership、当前佩戴体验卡和最终权益的唯一合并读模型。
	GetVipState(ctx context.Context, userID int64) (ledger.VipState, error)
	// BatchGetUserEffectiveVipLevels 用固定批量查询返回一页用户的最终等级，禁止调用方逐用户 GetVipState。
	BatchGetUserEffectiveVipLevels(ctx context.Context, userIDs []int64, nowMS int64) ([]ledger.UserEffectiveVipLevel, error)
	CheckVipBenefit(ctx context.Context, userID int64, benefitCode string) (ledger.CheckVipBenefitResult, error)
	// CheckVipResourceBenefit 校验具体资源是否仍绑定在当前 effective VIP 等级或其以下，
	// 功能型权益继续由 CheckVipBenefit 按当前等级完整矩阵判定。
	CheckVipResourceBenefit(ctx context.Context, userID int64, benefitCode string, resourceID int64, resourceType string) (ledger.CheckVipBenefitResult, error)
	PurchaseVip(ctx context.Context, command ledger.PurchaseVipCommand) (ledger.PurchaseVipReceipt, error)
	GrantVip(ctx context.Context, command ledger.GrantVipCommand) (ledger.GrantVipReceipt, error)
	GrantVipTrialCard(ctx context.Context, command ledger.GrantVipTrialCardCommand) (ledger.GrantVipTrialCardReceipt, error)
	EquipVipTrialCard(ctx context.Context, command ledger.EquipVipTrialCardCommand) (ledger.VipTrialCard, ledger.VipState, error)
	UnequipVipTrialCard(ctx context.Context, command ledger.UnequipVipTrialCardCommand) (bool, ledger.VipState, error)
	// ListAdminVipLevels 把 program 与完整等级配置作为一个不可拆分的后台读模型返回。
	ListAdminVipLevels(ctx context.Context) (ledger.VipProgramConfig, []ledger.VipLevel, error)
	UpdateAdminVipLevels(ctx context.Context, levels []ledger.AdminVipLevelCommand, operatorUserID int64) (ledger.VipProgramConfig, []ledger.VipLevel, error)
	UpdateAdminVipProgramConfig(ctx context.Context, command ledger.AdminVipProgramConfigCommand) (ledger.VipProgramConfig, error)
	UpdateVipUserSettings(ctx context.Context, command ledger.UpdateVipUserSettingsCommand) (ledger.VipUserSettings, error)
	// ProcessVipDailyCoinRebateBatch 创建或复用 UTC 日快照，并在同一事务推进唯一分页游标。
	ProcessVipDailyCoinRebateBatch(ctx context.Context, command ledger.ProcessVipDailyCoinRebateBatchCommand) (ledger.ProcessVipDailyCoinRebateBatchResult, error)
	GetMyCurrentVipDailyCoinRebate(ctx context.Context, userID int64, nowMS int64) (ledger.VipDailyCoinRebate, bool, error)
	ListMyVipDailyCoinRebateStatuses(ctx context.Context, query ledger.ListVipDailyCoinRebateStatusesQuery) ([]ledger.VipDailyCoinRebate, int64, error)
	ClaimVipDailyCoinRebate(ctx context.Context, command ledger.ClaimVipDailyCoinRebateCommand) (ledger.ClaimVipDailyCoinRebateReceipt, error)
}

// RedPacketStore 管理红包配置、创建、领取、查询和退款补偿。
type RedPacketStore interface {
	GetRedPacketConfig(ctx context.Context, appCode string) (ledger.RedPacketConfig, error)
	UpdateRedPacketConfig(ctx context.Context, config ledger.RedPacketConfig) (ledger.RedPacketConfig, error)
	CreateRedPacket(ctx context.Context, command ledger.RedPacketCreateCommand) (ledger.RedPacketCreateReceipt, error)
	ClaimRedPacket(ctx context.Context, command ledger.RedPacketClaimCommand) (ledger.RedPacketClaimReceipt, error)
	ListRedPackets(ctx context.Context, query ledger.RedPacketQuery) ([]ledger.RedPacket, int64, error)
	GetRedPacket(ctx context.Context, appCode string, packetID string, viewerUserID int64, includeClaims bool) (ledger.RedPacket, error)
	ExpireRedPackets(ctx context.Context, appCode string, batchSize int32) (ledger.RedPacketExpireResult, error)
	RetryRedPacketRefund(ctx context.Context, appCode string, packetID string, operatorUserID int64) (ledger.RedPacketRefundReceipt, error)
}

// ResourceCatalogStore 管理资源、资源组、礼物配置和礼物类型配置。
type ResourceCatalogStore interface {
	ListResources(ctx context.Context, query resourcedomain.ListResourcesQuery) ([]resourcedomain.Resource, int64, error)
	GetResource(ctx context.Context, resourceID int64) (resourcedomain.Resource, error)
	CreateResource(ctx context.Context, command resourcedomain.ResourceCommand) (resourcedomain.Resource, error)
	UpdateResource(ctx context.Context, command resourcedomain.ResourceCommand) (resourcedomain.Resource, error)
	SetResourceStatus(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.Resource, error)
	DeleteResource(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.Resource, error)
	BatchDeleteResources(ctx context.Context, command resourcedomain.BatchDeleteResourcesCommand) ([]resourcedomain.Resource, error)
	ListResourceGroups(ctx context.Context, query resourcedomain.ListResourceGroupsQuery) ([]resourcedomain.ResourceGroup, int64, error)
	GetResourceGroup(ctx context.Context, groupID int64) (resourcedomain.ResourceGroup, error)
	CreateResourceGroup(ctx context.Context, command resourcedomain.ResourceGroupCommand) (resourcedomain.ResourceGroup, error)
	UpdateResourceGroup(ctx context.Context, command resourcedomain.ResourceGroupCommand) (resourcedomain.ResourceGroup, error)
	SetResourceGroupStatus(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.ResourceGroup, error)
	ListGiftConfigs(ctx context.Context, query resourcedomain.ListGiftConfigsQuery) ([]resourcedomain.GiftConfig, int64, error)
	ListGiftTypeConfigs(ctx context.Context, query resourcedomain.ListGiftTypeConfigsQuery) ([]resourcedomain.GiftTypeConfig, error)
	GetGiftCatalogVersion(ctx context.Context, appCode string) (int64, error)
	CreateGiftConfig(ctx context.Context, command resourcedomain.GiftConfigCommand) (resourcedomain.GiftConfig, error)
	BatchCreateGiftConfigs(ctx context.Context, commands []resourcedomain.GiftConfigCommand) ([]resourcedomain.GiftConfig, error)
	UpdateGiftConfig(ctx context.Context, command resourcedomain.GiftConfigCommand) (resourcedomain.GiftConfig, error)
	SetGiftConfigStatus(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.GiftConfig, error)
	DeleteGiftConfig(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.GiftConfig, error)
	UpsertGiftTypeConfig(ctx context.Context, command resourcedomain.GiftTypeConfigCommand) (resourcedomain.GiftTypeConfig, error)
}

// ResourceGrantStore 管理资源发放和发放记录。
type ResourceGrantStore interface {
	GrantResource(ctx context.Context, command resourcedomain.GrantResourceCommand) (resourcedomain.ResourceGrant, error)
	GrantResourceGroup(ctx context.Context, command resourcedomain.GrantResourceGroupCommand) (resourcedomain.ResourceGrant, error)
	GetResourceGrant(ctx context.Context, grantID string) (resourcedomain.ResourceGrant, error)
	RevokeResourceGrant(ctx context.Context, command resourcedomain.RevokeResourceGrantCommand) (resourcedomain.ResourceGrant, error)
	ListResourceGrants(ctx context.Context, query resourcedomain.ListResourceGrantsQuery) ([]resourcedomain.ResourceGrant, int64, error)
}

// ResourceEquipmentStore 管理用户资源权益和穿戴状态。
type ResourceEquipmentStore interface {
	ListUserResources(ctx context.Context, query resourcedomain.ListUserResourcesQuery) ([]resourcedomain.UserResourceEntitlement, error)
	ListVipBenefitRequirementsForResource(ctx context.Context, resourceID int64) ([]resourcedomain.VipBenefitRequirement, error)
	ReplayEquipUserResource(ctx context.Context, command resourcedomain.EquipUserResourceCommand) (resourcedomain.UserResourceEntitlement, bool, error)
	RevokeUserResource(ctx context.Context, command resourcedomain.RevokeUserResourceCommand) (resourcedomain.UserResourceEntitlement, error)
	EquipUserResource(ctx context.Context, command resourcedomain.EquipUserResourceCommand) (resourcedomain.UserResourceEntitlement, error)
	UnequipUserResource(ctx context.Context, command resourcedomain.UnequipUserResourceCommand) (resourcedomain.UnequipUserResourceResult, error)
	BatchGetUserEquippedResources(ctx context.Context, query resourcedomain.BatchGetUserEquippedResourcesQuery) ([]resourcedomain.UserEquippedResources, error)
}

// ResourceShopStore 管理资源商城档位、购买记录和购买事务。
type ResourceShopStore interface {
	ListResourceShopItems(ctx context.Context, query resourcedomain.ListResourceShopItemsQuery) ([]resourcedomain.ResourceShopItem, int64, error)
	UpsertResourceShopItems(ctx context.Context, command resourcedomain.ResourceShopItemsCommand) ([]resourcedomain.ResourceShopItem, error)
	SetResourceShopItemStatus(ctx context.Context, command resourcedomain.ResourceShopItemStatusCommand) (resourcedomain.ResourceShopItem, error)
	ListResourceShopPurchaseOrders(ctx context.Context, query resourcedomain.ListResourceShopPurchaseOrdersQuery) ([]resourcedomain.ResourceShopPurchaseOrder, int64, error)
	PurchaseResourceShopItem(ctx context.Context, command resourcedomain.ResourceShopPurchaseCommand) (resourcedomain.ResourceShopPurchaseReceipt, error)
}

// WalletProjectionStore 管理钱包 outbox 到本地读模型的投影。
type WalletProjectionStore interface {
	ProjectPendingGiftWallEvents(ctx context.Context, workerID string, limit int, lockTTL time.Duration) (int, error)
	ProjectGiftWallMessage(ctx context.Context, workerID string, message walletmq.WalletOutboxMessage, lockTTL time.Duration) (bool, error)
}

// BadgeProjectionStore 管理 badge grant 事件投影到 activity-service 的投递位点。
type BadgeProjectionStore interface {
	ClaimPendingBadgeGrantEvents(ctx context.Context, workerID string, nowMS int64, lockTTL time.Duration, batchSize int) ([]resourcedomain.BadgeGrantOutbox, error)
	ClaimBadgeGrantMessage(ctx context.Context, workerID string, message walletmq.WalletOutboxMessage, nowMS int64, lockTTL time.Duration) (resourcedomain.BadgeGrantOutbox, bool, error)
	MarkBadgeGrantEventDelivered(ctx context.Context, event resourcedomain.BadgeGrantOutbox, nowMS int64) error
	MarkBadgeGrantEventFailed(ctx context.Context, event resourcedomain.BadgeGrantOutbox, failureReason string, nowMS int64) error
}
