// Package integration 定义 room-service 到外部服务的接口边界。
package integration

import (
	"context"

	roomeventsv1 "hyapp.local/api/proto/events/room/v1"
	luckygiftv1 "hyapp.local/api/proto/luckygift/v1"
	walletv1 "hyapp.local/api/proto/wallet/v1"
	"hyapp/pkg/tencentim"
)

// WalletClient 抽象 room-service 对 wallet-service 的同步账务和 VIP 权限事实依赖。
type WalletClient interface {
	// DebitGift 执行送礼扣费；失败时 room-service 不进入 Room Cell 状态提交。
	DebitGift(ctx context.Context, req *walletv1.DebitGiftRequest) (*walletv1.DebitGiftResponse, error)
	// BatchDebitGift 在 wallet-service 单事务内结算多目标送礼；任一目标失败时整批失败。
	BatchDebitGift(ctx context.Context, req *walletv1.BatchDebitGiftRequest) (*walletv1.BatchDebitGiftResponse, error)
	// DebitRobotGift 扣机器人专用金币；只用于机器人房间内部展示礼物。
	DebitRobotGift(ctx context.Context, req *walletv1.DebitRobotGiftRequest) (*walletv1.DebitGiftResponse, error)
	// GrantResourceGroup 发放火箭奖励资源组；命令 ID 必须由 room-service 按火箭结算事实生成。
	GrantResourceGroup(ctx context.Context, req *walletv1.GrantResourceGroupRequest) (*walletv1.ResourceGrantResponse, error)
	// GetMyVip 读取 wallet-service 已合并付费 VIP 与当前佩戴体验卡后的唯一 effective state。
	// room-service 只消费 effective_benefits，不自行按等级或 app_code 推导房间权限。
	GetMyVip(ctx context.Context, req *walletv1.GetMyVipRequest) (*walletv1.GetMyVipResponse, error)
}

// WalletVIPBenefitClient 是新版 VIP 单项权益校验的可选能力。它独立于 WalletClient，
// 避免房间测试里的轻量账务 fake 因新增只读 RPC 被迫实现无关方法；生产 gRPC client 必须实现。
type WalletVIPBenefitClient interface {
	CheckVipBenefit(ctx context.Context, req *walletv1.CheckVipBenefitRequest) (*walletv1.CheckVipBenefitResponse, error)
}

// WalletUserResourceClient 是房间装扮读取用户有效资源的可选能力。资源归 wallet owner，
// room-service 只钉住应用时的展示快照，不能复制 entitlement 有效期和数量算法。
type WalletUserResourceClient interface {
	ListUserResources(ctx context.Context, req *walletv1.ListUserResourcesRequest) (*walletv1.ListUserResourcesResponse, error)
}

// LuckyGiftClient 抽象 room-service 对 lucky-gift-service 幸运礼物抽奖边界的同步依赖。
type LuckyGiftClient interface {
	// CheckLuckyGift 在扣费前确认奖池规则可用；失败时不能扣费。
	CheckLuckyGift(ctx context.Context, req *luckygiftv1.CheckLuckyGiftRequest) (*luckygiftv1.CheckLuckyGiftResponse, error)
	// ExecuteLuckyGiftDraw 在钱包扣费成功后按 command_id 幂等落抽奖事实。
	ExecuteLuckyGiftDraw(ctx context.Context, req *luckygiftv1.ExecuteLuckyGiftDrawRequest) (*luckygiftv1.ExecuteLuckyGiftDrawResponse, error)
	// BatchExecuteLuckyGiftDraw 一次提交多人送礼的全部目标抽奖事实，返回顺序必须和请求目标顺序一致。
	BatchExecuteLuckyGiftDraw(ctx context.Context, req *luckygiftv1.BatchExecuteLuckyGiftDrawRequest) (*luckygiftv1.BatchExecuteLuckyGiftDrawResponse, error)
}

// RoomEventPublisher 保留腾讯云 IM 直接桥接能力；房间命令主链路不再调用它。
type RoomEventPublisher interface {
	// EnsureRoomGroup 确保房间在腾讯云 IM 中有对应群组。
	EnsureRoomGroup(ctx context.Context, roomID string, ownerUserID int64) error
	// PublishRoomEvent 把房间系统事件推给腾讯云 IM，当前只供异步边界复用。
	PublishRoomEvent(ctx context.Context, event tencentim.RoomEvent) error
}

// RTCUserRemover 抽象 room-service 对腾讯 RTC 实时房间的服务端踢人能力。
// 连接态仍在腾讯 RTC，Room Cell 只在状态提交后触发这个外部副作用。
type RTCUserRemover interface {
	RemoveUserByStrRoomID(ctx context.Context, roomID string, userID int64) error
}

// RTCUserAudioBlocker 抽象腾讯 RTC 媒体平面的服务端音频开关。
// Room Cell 仍是禁言事实 owner；实现只能投影当前状态，不能自行持有禁言集合。
type RTCUserAudioBlocker interface {
	SetUserAudioBlockedByStrRoomID(ctx context.Context, roomID string, userID int64, blocked bool) error
}

// IMUserMuter 抽象腾讯 IM 群成员禁言投影。
// Room Cell 仍是唯一权威状态；实现只修改指定房间群和指定用户，绝不能注册消息发送前回调。
type IMUserMuter interface {
	SetRoomGroupMemberMuted(ctx context.Context, roomID string, userID int64, muted bool) error
}

// OutboxPublisher 抽象 outbox worker 对外部消费者的异步投递。
type OutboxPublisher interface {
	// PublishOutboxEvent 投递 protobuf outbox 信封，失败由 room_outbox 转为 retryable 状态重试。
	PublishOutboxEvent(ctx context.Context, envelope *roomeventsv1.EventEnvelope) error
}

// RoomRocketLaunchSchedule 是 RoomRocketIgnited 派生出的延迟发射唤醒任务。
type RoomRocketLaunchSchedule struct {
	AppCode    string
	RoomID     string
	RocketID   string
	Level      int32
	LaunchAtMS int64
	ResetAtMS  int64
	CommandID  string
}

// RoomRocketLaunchScheduler 抽象“到 launch_at_ms 唤醒 room-service”的外部延迟通道。
type RoomRocketLaunchScheduler interface {
	// ScheduleRoomRocketLaunch 只负责安排唤醒；真正发射仍由 room-service 命令链路校验并提交。
	ScheduleRoomRocketLaunch(ctx context.Context, schedule RoomRocketLaunchSchedule) error
}
