package luckygift

import (
	"testing"

	activityv1 "hyapp.local/api/proto/activity/v1"
)

func TestConfigToProtoConvertsBusinessUnitsToPPM(t *testing.T) {
	config := configToProto(configRequest{
		PoolID:                   " lucky_100 ",
		Enabled:                  true,
		TargetRTPPercent:         95,
		PoolRatePercent:          96,
		SettlementWindowWager:    1_000_000,
		ControlBandPercent:       1,
		GiftPriceReference:       100,
		NoviceMaxEquivalentDraws: 2_000,
		NormalMaxEquivalentDraws: 20_000,
		Stages: []stageDTO{
			{
				Stage: " novice ",
				Tiers: []tierDTO{
					{
						TierID:             " novice_0_3x ",
						Multiplier:         0.3,
						ProbabilityPercent: 22,
						RewardSource:       " base_rtp ",
						BroadcastLevel:     " room ",
						Enabled:            true,
					},
				},
			},
		},
	})

	if config.GetPoolId() != "lucky_100" {
		t.Fatalf("pool id = %q, want lucky_100", config.GetPoolId())
	}
	if config.GetTargetRtpPpm() != 950_000 {
		t.Fatalf("target rtp ppm = %d, want 950000", config.GetTargetRtpPpm())
	}
	if config.GetPoolRatePpm() != 960_000 {
		t.Fatalf("pool rate ppm = %d, want 960000", config.GetPoolRatePpm())
	}
	if config.GetControlBandPpm() != 10_000 {
		t.Fatalf("control band ppm = %d, want 10000", config.GetControlBandPpm())
	}
	if config.GetNoviceMaxEquivalentDraws() != 2_000 || config.GetNormalMaxEquivalentDraws() != 20_000 {
		t.Fatalf("equivalent draw thresholds mismatch: novice=%d normal=%d", config.GetNoviceMaxEquivalentDraws(), config.GetNormalMaxEquivalentDraws())
	}
	tier := config.GetStages()[0].GetTiers()[0]
	if tier.GetStage() != "novice" {
		t.Fatalf("tier stage = %q, want novice", tier.GetStage())
	}
	if tier.GetTierId() != "novice_0_3x" {
		t.Fatalf("tier id = %q, want novice_0_3x", tier.GetTierId())
	}
	if tier.GetMultiplierPpm() != 300_000 {
		t.Fatalf("multiplier ppm = %d, want 300000", tier.GetMultiplierPpm())
	}
	if tier.GetBaseWeightPpm() != 220_000 {
		t.Fatalf("base weight ppm = %d, want 220000", tier.GetBaseWeightPpm())
	}
}

func TestConfigToProtoGeneratesUniqueTierIDs(t *testing.T) {
	config := configToProto(configRequest{
		PoolID: "lucky",
		Stages: []stageDTO{
			{
				Stage: "advanced",
				Tiers: []tierDTO{
					{TierID: "manual_one", Multiplier: 0, ProbabilityPercent: 50, RewardSource: "base_rtp", Enabled: true},
					{TierID: "manual_two", Multiplier: 5, ProbabilityPercent: 25, RewardSource: "base_rtp", Enabled: true},
					{TierID: "manual_two", Multiplier: 5, ProbabilityPercent: 25, RewardSource: "base_rtp", Enabled: true},
					{TierID: "manual_decimal", Multiplier: 0.5, ProbabilityPercent: 0, RewardSource: "base_rtp"},
				},
			},
		},
	})

	tiers := config.GetStages()[0].GetTiers()
	got := []string{tiers[0].GetTierId(), tiers[1].GetTierId(), tiers[2].GetTierId(), tiers[3].GetTierId()}
	want := []string{"advanced_none", "advanced_5x", "advanced_5x_2", "advanced_0_5x"}
	for index := range want {
		if got[index] != want[index] {
			t.Fatalf("tier id[%d] = %q, want %q; all=%v", index, got[index], want[index], got)
		}
	}
}

func TestConfigFromProtoConvertsPPMToBusinessUnits(t *testing.T) {
	config := configFromProto(&activityv1.LuckyGiftRuleConfig{
		AppCode:                  "hyapp",
		PoolId:                   "lucky_100",
		RuleVersion:              7,
		Enabled:                  true,
		TargetRtpPpm:             950_000,
		PoolRatePpm:              960_000,
		SettlementWindowWager:    1_000_000,
		ControlBandPpm:           10_000,
		GiftPriceReference:       100,
		NoviceMaxEquivalentDraws: 2_000,
		NormalMaxEquivalentDraws: 20_000,
		MaxSinglePayout:          50_000,
		UserHourlyPayoutCap:      34_200,
		UserDailyPayoutCap:       615_600,
		DeviceDailyPayoutCap:     1_026_000,
		RoomHourlyPayoutCap:      684_000,
		AnchorDailyPayoutCap:     12_312_000,
		CreatedByAdminId:         12,
		CreatedAtMs:              1_700_000_000_000,
		Stages: []*activityv1.LuckyGiftRuleStage{
			{
				Stage: "novice",
				Tiers: []*activityv1.LuckyGiftRuleTier{
					{
						TierId:         "novice_0_3x",
						MultiplierPpm:  300_000,
						BaseWeightPpm:  220_000,
						RewardSource:   "base_rtp",
						BroadcastLevel: "room",
						Enabled:        true,
					},
				},
			},
		},
	})

	if config.TargetRTPPercent != 95 {
		t.Fatalf("target rtp percent = %v, want 95", config.TargetRTPPercent)
	}
	if config.PoolRatePercent != 96 {
		t.Fatalf("pool rate percent = %v, want 96", config.PoolRatePercent)
	}
	if config.ControlBandPercent != 1 {
		t.Fatalf("control band percent = %v, want 1", config.ControlBandPercent)
	}
	if config.RoomHourlyPayoutCap != 684_000 || config.AnchorDailyPayoutCap != 12_312_000 {
		t.Fatalf("risk caps were not copied from proto: room=%d anchor=%d", config.RoomHourlyPayoutCap, config.AnchorDailyPayoutCap)
	}
	if config.NoviceMaxEquivalentDraws != 2_000 || config.NormalMaxEquivalentDraws != 20_000 {
		t.Fatalf("equivalent draw thresholds were not copied from proto: novice=%d normal=%d", config.NoviceMaxEquivalentDraws, config.NormalMaxEquivalentDraws)
	}
	if config.Stages[0].Tiers[0].Multiplier != 0.3 {
		t.Fatalf("multiplier = %v, want 0.3", config.Stages[0].Tiers[0].Multiplier)
	}
	if config.Stages[0].Tiers[0].ProbabilityPercent != 22 {
		t.Fatalf("probability percent = %v, want 22", config.Stages[0].Tiers[0].ProbabilityPercent)
	}
}
