package plugin

import (
	"strings"
	"testing"
)

func TestRenderCombatLog_ProducesMessages(t *testing.T) {
	player := Combatant{
		Name:     "Hero",
		Stats:    CombatStats{MaxHP: 100, Attack: 20, Defense: 10, Speed: 8, CritRate: 0.05},
		Mods:     CombatModifiers{DamageReduct: 1.0},
		IsPlayer: true,
	}
	enemy := Combatant{
		Name:  "Goblin",
		Stats: CombatStats{MaxHP: 60, Attack: 12, Defense: 5, Speed: 6, CritRate: 0.03},
		Mods:  CombatModifiers{DamageReduct: 1.0},
	}

	result := SimulateCombat(player, enemy, defaultCombatPhases)
	msgs := RenderCombatLog(result, "Hero", "Goblin")

	if len(msgs) < 1 {
		t.Fatalf("expected at least 1 phase message, got %d", len(msgs))
	}
}

func TestRenderCombatLog_PhaseHeaders(t *testing.T) {
	player := Combatant{
		Name:     "Hero",
		Stats:    CombatStats{MaxHP: 100, Attack: 20, Defense: 10, Speed: 8, CritRate: 0.05},
		Mods:     CombatModifiers{DamageReduct: 1.0},
		IsPlayer: true,
	}
	enemy := Combatant{
		Name:  "Rat",
		Stats: CombatStats{MaxHP: 40, Attack: 8, Defense: 3, Speed: 4},
		Mods:  CombatModifiers{DamageReduct: 1.0},
	}

	result := SimulateCombat(player, enemy, defaultCombatPhases)
	msgs := RenderCombatLog(result, "Hero", "Rat")

	hasOpening := false
	for _, m := range msgs {
		if strings.Contains(m, "Opening") {
			hasOpening = true
		}
	}
	if !hasOpening {
		t.Error("should have an Opening phase header")
	}
}

func TestRenderCombatLog_WinPhaseMessages(t *testing.T) {
	result := CombatResult{
		PlayerWon:     true,
		PlayerStartHP: 100,
		EnemyStartHP:  50,
		PlayerEndHP:   80,
		EnemyEndHP:    0,
		TotalRounds:   3,
		Closeness:     0.2,
		Events: []CombatEvent{
			{Round: 1, Phase: "opening", Actor: "player", Action: "hit", Damage: 25, EnemyHP: 25, PlayerHP: 100},
			{Round: 2, Phase: "clash", Actor: "player", Action: "hit", Damage: 25, EnemyHP: 0, PlayerHP: 80},
		},
	}

	msgs := RenderCombatLog(result, "Hero", "Slime")

	if len(msgs) < 1 {
		t.Fatalf("expected at least 1 phase message, got %d", len(msgs))
	}
	// Phase messages should contain damage numbers
	found := false
	for _, m := range msgs {
		if strings.Contains(m, "25") {
			found = true
		}
	}
	if !found {
		t.Error("phase messages should contain damage values")
	}
}

func TestRenderCombatLog_LossPhaseMessages(t *testing.T) {
	result := CombatResult{
		PlayerWon:     false,
		PlayerStartHP: 100,
		EnemyStartHP:  80,
		PlayerEndHP:   0,
		EnemyEndHP:    40,
		TotalRounds:   4,
		Closeness:     0.5,
		Events: []CombatEvent{
			{Round: 1, Phase: "opening", Actor: "enemy", Action: "hit", Damage: 50, PlayerHP: 50, EnemyHP: 80},
			{Round: 2, Phase: "clash", Actor: "enemy", Action: "hit", Damage: 50, PlayerHP: 0, EnemyHP: 80},
		},
	}

	msgs := RenderCombatLog(result, "Hero", "Dragon")
	if len(msgs) < 1 {
		t.Fatalf("expected at least 1 phase message, got %d", len(msgs))
	}
}

func TestRenderCombatLog_ConsumableEvents(t *testing.T) {
	result := CombatResult{
		PlayerWon:     true,
		PlayerStartHP: 100,
		EnemyStartHP:  60,
		PlayerEndHP:   80,
		EnemyEndHP:    0,
		Events: []CombatEvent{
			{Round: 0, Phase: "pre_combat", Actor: "consumable", Action: "use_consumable", Desc: "Goblin Grease"},
			{Round: 0, Phase: "pre_combat", Actor: "consumable", Action: "flat_damage", Damage: 8, PlayerHP: 100, EnemyHP: 52},
			{Round: 1, Phase: "opening", Actor: "player", Action: "hit", Damage: 30, PlayerHP: 100, EnemyHP: 22},
			{Round: 2, Phase: "clash", Actor: "player", Action: "hit", Damage: 22, PlayerHP: 80, EnemyHP: 0},
		},
	}

	msgs := RenderCombatLog(result, "Hero", "Imp")

	found := false
	for _, m := range msgs {
		if strings.Contains(m, "Goblin Grease") {
			found = true
		}
	}
	if !found {
		t.Error("should render consumable use event mentioning item name")
	}
}

func TestRenderCombatLog_MonsterAbilityEvents(t *testing.T) {
	result := CombatResult{
		PlayerWon:     true,
		PlayerStartHP: 100,
		EnemyStartHP:  60,
		PlayerEndHP:   50,
		EnemyEndHP:    0,
		Events: []CombatEvent{
			{Round: 1, Phase: "opening", Actor: "enemy", Action: "armor_break", Damage: 0, PlayerHP: 100, EnemyHP: 60},
			{Round: 1, Phase: "opening", Actor: "player", Action: "hit", Damage: 30, PlayerHP: 100, EnemyHP: 30},
			{Round: 2, Phase: "clash", Actor: "enemy", Action: "hit", Damage: 25, PlayerHP: 75, EnemyHP: 30},
			{Round: 2, Phase: "clash", Actor: "enemy", Action: "poison_tick", Damage: 5, PlayerHP: 70, EnemyHP: 30},
			{Round: 3, Phase: "decisive", Actor: "player", Action: "crit", Damage: 30, PlayerHP: 50, EnemyHP: 0},
		},
	}

	msgs := RenderCombatLog(result, "Hero", "Wyrm")

	hasArmorBreak := false
	hasPoison := false
	for _, m := range msgs {
		if strings.Contains(m, "armor") || strings.Contains(m, "Armor") || strings.Contains(m, "defense") || strings.Contains(m, "Defense") {
			hasArmorBreak = true
		}
		if strings.Contains(m, "poison") || strings.Contains(m, "Poison") || strings.Contains(m, "toxin") || strings.Contains(m, "Venom") || strings.Contains(m, "venom") {
			hasPoison = true
		}
	}
	if !hasArmorBreak {
		t.Error("should render armor_break event")
	}
	if !hasPoison {
		t.Error("should render poison_tick event")
	}
}
