package integration

import (
	"context"
	"time"

	activityv1 "hyapp.local/api/proto/activity/v1"
	roomeventsv1 "hyapp.local/api/proto/events/room/v1"
	"hyapp/pkg/appcode"
)

// ActivityOutboxPublisher 把已经提交的 room outbox 事实转发给 activity-service。
// 它是 best-effort 桥接：转发失败不回滚 Room Cell，因为房间状态和 command log 已经是权威事实。
type ActivityOutboxPublisher struct {
	client  activityv1.RoomEventConsumerServiceClient
	timeout time.Duration
}

// NewActivityOutboxPublisher 创建 room-service 到 activity-service 的事件消费桥。
// timeout 较短是有意的，避免活动/播报服务慢调用拖住房间命令返回。
func NewActivityOutboxPublisher(client activityv1.RoomEventConsumerServiceClient, timeout time.Duration) *ActivityOutboxPublisher {
	if timeout <= 0 {
		timeout = time.Second
	}
	return &ActivityOutboxPublisher{client: client, timeout: timeout}
}

// PublishOutboxEvent 发送一条 protobuf room outbox envelope。
// RequestMeta 使用 envelope event_id 作为 request_id，排查链路时能直接从房间事件定位到活动消费日志。
func (p *ActivityOutboxPublisher) PublishOutboxEvent(ctx context.Context, envelope *roomeventsv1.EventEnvelope) error {
	if p == nil || p.client == nil || envelope == nil {
		// 未配置 activity-service 时保持 no-op，保证房间核心链路可独立运行。
		return nil
	}
	callCtx, cancel := context.WithTimeout(appcode.WithContext(ctx, envelope.GetAppCode()), p.timeout)
	defer cancel()
	_, err := p.client.ConsumeRoomEvent(callCtx, &activityv1.ConsumeRoomEventRequest{
		Meta: &activityv1.RequestMeta{
			RequestId: envelope.GetEventId(),
			Caller:    "room-service",
			SentAtMs:  time.Now().UTC().UnixMilli(),
			AppCode:   envelope.GetAppCode(),
		},
		Envelope: envelope,
	})
	return err
}
