package app

import (
	"strings"
	"testing"

	"hyapp/pkg/roommq"
	"hyapp/services/activity-service/internal/config"
)

func TestRoomOutboxConsumerConfigSerializesCompositeProjection(t *testing.T) {
	cfg := config.Default().RocketMQ
	cfg.RoomOutbox.ConsumerGroup = "activity-room-outbox-test"

	consumerConfig := roomOutboxConsumerConfig(cfg)
	if consumerConfig.ConsumeGoroutines != 1 {
		t.Fatalf("room outbox consume goroutines = %d, want 1", consumerConfig.ConsumeGoroutines)
	}
	if consumerConfig.GroupName != cfg.RoomOutbox.ConsumerGroup {
		t.Fatalf("room outbox group = %q, want %q", consumerConfig.GroupName, cfg.RoomOutbox.ConsumerGroup)
	}
}

func TestActivityTemplateRoomConsumerUsesIndependentGiftProjectionGroup(t *testing.T) {
	cfg := config.Default().RocketMQ
	cfg.RoomOutbox.ConsumerGroup = "activity-room-composite-test"
	cfg.RoomOutbox.ActivityTemplateConsumerGroup = "activity-template-gift-test"
	consumerConfig := activityTemplateRoomOutboxConsumerConfig(cfg)
	if consumerConfig.GroupName != cfg.RoomOutbox.ActivityTemplateConsumerGroup || consumerConfig.GroupName == cfg.RoomOutbox.ConsumerGroup {
		t.Fatalf("activity template consumer must own an independent offset: %+v", consumerConfig)
	}
	if consumerConfig.ConsumeGoroutines != 1 {
		t.Fatalf("activity template gift consumer goroutines = %d, want 1", consumerConfig.ConsumeGoroutines)
	}
}

func TestLuckyGiftOutboxConsumerUsesIndependentRealtimeGroup(t *testing.T) {
	cfg := config.Default().RocketMQ
	cfg.LuckyGiftOutbox.ConsumerGroup = "activity-lucky-gift-test"

	consumerConfig := luckyGiftOutboxConsumerConfig(cfg)
	if consumerConfig.GroupName != cfg.LuckyGiftOutbox.ConsumerGroup {
		t.Fatalf("lucky gift outbox group = %q, want %q", consumerConfig.GroupName, cfg.LuckyGiftOutbox.ConsumerGroup)
	}
	if consumerConfig.GroupName == cfg.RoomOutbox.ConsumerGroup || consumerConfig.GroupName == cfg.WalletOutbox.RedPacketBroadcastConsumerGroup {
		t.Fatalf("lucky gift outbox must not share another projection offset: %+v", consumerConfig)
	}
	if consumerConfig.ConsumeFromFirst {
		t.Fatal("lucky gift top-banner consumer must not replay historical wins for a new group")
	}
}

func TestGameOutboxConsumerUsesIndependentRealtimeGroup(t *testing.T) {
	cfg := config.Default().RocketMQ
	cfg.GameOutbox.ConsumerGroup = "activity-game-win-test"

	consumerConfig := gameOutboxConsumerConfig(cfg)
	if consumerConfig.GroupName != cfg.GameOutbox.ConsumerGroup {
		t.Fatalf("game outbox group = %q, want %q", consumerConfig.GroupName, cfg.GameOutbox.ConsumerGroup)
	}
	if consumerConfig.GroupName == cfg.RoomOutbox.ConsumerGroup || consumerConfig.GroupName == cfg.LuckyGiftOutbox.ConsumerGroup {
		t.Fatalf("game_win must own an independent MQ offset: %+v", consumerConfig)
	}
	if consumerConfig.ConsumeFromFirst {
		t.Fatal("game_win consumer must not replay historical payouts for a new group")
	}
}

func TestActivityRoomSelectorKeepsLegacyAndOnlyRelevantTypedEvents(t *testing.T) {
	expression, err := roommq.LegacyCompatibleTagExpression(activityRoomEventTypes()...)
	if err != nil {
		t.Fatalf("LegacyCompatibleTagExpression failed: %v", err)
	}
	for _, required := range []string{
		roommq.TagRoomOutboxEvent,
		roommq.EventTypeRoomGiftSent,
		roommq.EventTypeRoomPasswordChanged,
		roommq.EventTypeRoomRocketIgnited,
		roommq.EventTypeRoomRocketRewardGranted,
	} {
		if !strings.Contains(expression, required) {
			t.Fatalf("activity room selector %q misses %q", expression, required)
		}
	}
	if strings.Contains(expression, roommq.EventTypeRoomMicChanged) {
		t.Fatalf("activity room selector must not receive mic events: %q", expression)
	}
}

func TestVIPRebateNoticeConsumerDoesNotReplayHistoricalWalletEvents(t *testing.T) {
	cfg := config.Default().RocketMQ
	cfg.WalletOutbox.VIPRebateNoticeConsumerGroup = "activity-vip-rebate-notice-test"

	consumerConfig := walletOutboxVIPRebateNoticeConsumerConfig(cfg)
	if consumerConfig.ConsumeFromFirst {
		t.Fatal("VIP rebate notice consumer must start at the latest offset for a new group")
	}
	if consumerConfig.GroupName != cfg.WalletOutbox.VIPRebateNoticeConsumerGroup {
		t.Fatalf("VIP rebate notice group = %q, want %q", consumerConfig.GroupName, cfg.WalletOutbox.VIPRebateNoticeConsumerGroup)
	}
}
