package store

import "testing"

func TestEstimateTokens_DefaultConfig(t *testing.T) {
	config := GetDefaultStrategyConfig("en")
	est := config.EstimateTokens()

	if est.Total <= 0 {
		t.Errorf("expected positive token estimate, got %d", est.Total)
	}
	if est.Total > 200000 {
		t.Errorf("token estimate %d seems unreasonably high for default config", est.Total)
	}

	// Breakdown should sum approximately to total (before 15% margin)
	subtotal := est.Breakdown.SystemPrompt + est.Breakdown.MarketData +
		est.Breakdown.RankingData + est.Breakdown.QuantData + est.Breakdown.FixedOverhead
	expectedTotal := subtotal * 115 / 100
	if est.Total != expectedTotal {
		t.Errorf("total %d != breakdown subtotal %d * 1.15 = %d", est.Total, subtotal, expectedTotal)
	}

	// Should have model limits
	if len(est.ModelLimits) == 0 {
		t.Error("expected model limits to be populated")
	}

	// Default config should be ok for all models
	for _, ml := range est.ModelLimits {
		if ml.Level == "danger" {
			t.Errorf("default config should not exceed %s limit, got %d%%", ml.Name, ml.UsagePct)
		}
	}
}

func TestEstimateTokens_ZhVsEn(t *testing.T) {
	enConfig := GetDefaultStrategyConfig("en")
	zhConfig := GetDefaultStrategyConfig("zh")

	enEst := enConfig.EstimateTokens()
	zhEst := zhConfig.EstimateTokens()

	// Chinese config should have more tokens for system prompt due to CJK encoding
	// but total can vary — just ensure both are reasonable
	if enEst.Total <= 0 || zhEst.Total <= 0 {
		t.Errorf("both estimates should be positive: en=%d, zh=%d", enEst.Total, zhEst.Total)
	}
}

func TestEstimateTokens_HighConfig(t *testing.T) {
	config := GetDefaultStrategyConfig("en")
	// Push config to extremes (beyond clamped limits)
	config.CoinSource.SourceType = "static"
	config.CoinSource.StaticCoins = []string{"BTCUSDT", "ETHUSDT", "SOLUSDT", "DOGEUSDT", "XRPUSDT"}
	config.Indicators.Klines.SelectedTimeframes = []string{"1m", "3m", "5m", "15m", "1h", "4h"}
	config.Indicators.Klines.PrimaryCount = 100
	config.Indicators.EnableEMA = true
	config.Indicators.EnableMACD = true
	config.Indicators.EnableRSI = true
	config.Indicators.EnableATR = true
	config.Indicators.EnableBOLL = true

	est := config.EstimateTokens()

	// Should produce a higher estimate than default
	defaultCfg := GetDefaultStrategyConfig("en")
	defaultEst := defaultCfg.EstimateTokens()
	if est.Total <= defaultEst.Total {
		t.Errorf("high config estimate %d should be greater than default %d", est.Total, defaultEst.Total)
	}

	// Should have some models in warning/danger
	hasDanger := false
	for _, ml := range est.ModelLimits {
		if ml.Level == "danger" || ml.Level == "warning" {
			hasDanger = true
			break
		}
	}
	// With 5 coins * 6 timeframes * 100 klines, this should exceed small models
	if !hasDanger {
		t.Logf("high config estimate: %d tokens", est.Total)
	}
}

func TestGetContextLimit(t *testing.T) {
	if got := GetContextLimit("deepseek"); got != 131072 {
		t.Errorf("deepseek limit = %d, want 131072", got)
	}
	if got := GetContextLimit("unknown_provider"); got != 131072 {
		t.Errorf("unknown provider should return default 131072, got %d", got)
	}
}

func TestGetEffectiveCoinCount(t *testing.T) {
	config := StrategyConfig{
		CoinSource: CoinSourceConfig{
			SourceType:  "static",
			StaticCoins: []string{"BTCUSDT", "ETHUSDT"},
		},
	}
	if got := config.getEffectiveCoinCount(); got != 2 {
		t.Errorf("static coin count = %d, want 2", got)
	}

	config.CoinSource.SourceType = "ai500"
	config.CoinSource.AI500Limit = 5
	if got := config.getEffectiveCoinCount(); got != 5 {
		t.Errorf("ai500 coin count = %d, want 5", got)
	}
}
