package game

import (
	"testing"
	"time"
)

func TestBalanceMonteCarlo_WolfMedianGear(t *testing.T) {
	n := 8000
	if testing.Short() {
		n = 1500
	}
	const seed = 424242
	level := 5
	r := RunBalanceMonteCarlo(level, n, seed, ReferenceGearMedian, BalanceEnemyWolfOnly)
	t.Logf("level=%d wolf-only median-gear: win=%.3f med=%s p90=%s mean=%s (n=%d)",
		level, r.WinRate, r.MedianDur.Round(time.Millisecond), r.P90Dur.Round(time.Millisecond), r.MeanDur.Round(time.Millisecond), n)
	if r.Iterations != n {
		t.Fatalf("iterations: got %d want %d", r.Iterations, n)
	}
}

func TestBalanceMonteCarlo_MixedSpawnL10(t *testing.T) {
	if testing.Short() {
		t.Skip()
	}
	const n = 4000
	const seed = 777
	r := RunBalanceMonteCarlo(10, n, seed, ReferenceGearRolled, BalanceEnemyMixedSpawn)
	t.Logf("level=10 mixed rolled-gear: win=%.3f med=%s p90=%s", r.WinRate, r.MedianDur.Round(time.Millisecond), r.P90Dur.Round(time.Millisecond))
}

func TestBalanceMonteCarlo_WolfCurve(t *testing.T) {
	if testing.Short() {
		t.Skip()
	}
	const n = 6000
	const seed = 99
	for _, level := range []int{5, 10, 15, 20, 25} {
		r := RunBalanceMonteCarlo(level, n, seed+int64(level*17), ReferenceGearMedian, BalanceEnemyWolfOnly)
		t.Logf("L%2d wolf-only median-gear: win=%.3f med=%s p90=%s", level, r.WinRate, r.MedianDur.Round(time.Millisecond), r.P90Dur.Round(time.Millisecond))
	}
}

func TestBalanceMonteCarlo_CurveProbe(t *testing.T) {
	if testing.Short() {
		t.Skip("curve probe")
	}
	const n = 5000
	const seed = 2026
	for _, level := range []int{1, 3, 5, 10, 15, 20} {
		r := RunBalanceMonteCarlo(level, n, seed+int64(level), ReferenceGearMedian, BalanceEnemyMixedSpawn)
		t.Logf("L%2d mixed median-gear: win=%.3f med=%s p90=%s", level, r.WinRate, r.MedianDur.Round(time.Millisecond), r.P90Dur.Round(time.Millisecond))
	}
}

// TestBalanceMonteCarlo_L5MixedRegression guards against extreme drift after tuning changes.
func TestBalanceMonteCarlo_L5MixedRegression(t *testing.T) {
	if testing.Short() {
		t.Skip()
	}
	const n = 4000
	r := RunBalanceMonteCarlo(5, n, 424242, ReferenceGearMedian, BalanceEnemyMixedSpawn)
	if r.WinRate < 0.30 || r.WinRate > 1.00 {
		t.Fatalf("L5 mixed win rate drift: %.3f (expected rough band 0.30–1.00)", r.WinRate)
	}
	// Mixed spawn has high variance; median duration should stay in a sane band after pace/damage retunes.
	if r.MedianDur < 90*time.Second || r.MedianDur > 12*time.Minute {
		t.Fatalf("L5 mixed median duration drift: %s (expected rough ~1.5–10 min band)", r.MedianDur)
	}
}
