package main

import "testing"

func TestCheckBankruptciesReplacesBot(t *testing.T) {
	m := NewModel()
	// делаем бота-1 банкротом
	m.game.Players[1].Balance = 0
	oldName := m.game.Players[1].Name

	msg := m.checkBankruptcies()
	if msg == "" {
		t.Fatalf("ожидалось сообщение о банкротстве")
	}
	if m.game.Players[1].Name == oldName {
		t.Errorf("имя обанкротившегося бота должно было смениться")
	}
	if m.game.Players[1].Balance != m.game.StartingCapital {
		t.Errorf("новый бот должен получить стартовый капитал %d, получено %d",
			m.game.StartingCapital, m.game.Players[1].Balance)
	}
	if m.game.Players[1].IsHuman {
		t.Errorf("заменённое место не должно быть отмечено как человек")
	}
	if _, ok := m.bots[1]; !ok {
		t.Errorf("для места 1 должен быть назначен новый бот в m.bots")
	}
}

func TestCheckBankruptciesReplacesHuman(t *testing.T) {
	m := NewModel()
	m.game.Players[m.humanIdx].Balance = -5 // ушёл в минус

	msg := m.checkBankruptcies()
	if msg == "" {
		t.Fatalf("ожидалось сообщение о банкротстве человека")
	}
	if m.humanIdx != -1 {
		t.Fatalf("после банкротства человека humanIdx должен стать -1, получено %d", m.humanIdx)
	}
	if m.game.Players[0].IsHuman {
		t.Errorf("бывшее место человека не должно остаться отмеченным как человек")
	}
	if _, ok := m.bots[0]; !ok {
		t.Errorf("для бывшего места человека должен быть назначен бот")
	}
}

func TestCheckBankruptciesNoneWhenSolvent(t *testing.T) {
	m := NewModel()
	msg := m.checkBankruptcies()
	if msg != "" {
		t.Errorf("не ожидалось сообщений о банкротстве при положительных балансах, получено: %q", msg)
	}
}

func TestStartNewRoundReplacesAndDealsBankruptPlayer(t *testing.T) {
	m := NewModel()
	m.game.Players[2].Balance = 0
	// доводим раунд до конца, чтобы можно было легально стартовать новый
	m.game.Players[m.humanIdx].Hand = []Card{c(Ace, Clubs)}
	m.game.CurrentPlayer = m.humanIdx
	m.game.Phase = PhaseAction
	if err := m.game.Discard(c(Ace, Clubs)); err != nil {
		t.Fatalf("не удалось завершить раунд для теста: %v", err)
	}

	m.startNewRound()

	if len(m.game.Players[2].Hand) != 5 {
		t.Fatalf("новый бот должен получить обычную раздачу из 5 карт, получено %d",
			len(m.game.Players[2].Hand))
	}
	if m.message == "" {
		t.Errorf("ожидалось информационное сообщение о замене игрока")
	}
}

func TestRandomBotStrategyReturnsKnownLevel(t *testing.T) {
	seenLevels := map[string]bool{}
	for i := 0; i < 100; i++ {
		_, level := randomBotStrategy()
		seenLevels[level] = true
	}
	if len(seenLevels) == 0 {
		t.Fatalf("randomBotStrategy не вернула ни одного уровня")
	}
	for level := range seenLevels {
		found := false
		for _, l := range botLevels {
			if l.Suffix == level {
				found = true
				break
			}
		}
		if !found {
			t.Errorf("неизвестный уровень бота: %q", level)
		}
	}
}
