package classes

import (
	"math/rand"
	"strings"
	"sync"
	"testing"
	"time"
)

// Mock entity implementations for testing
type MockClassAware struct {
	classID int8
	mutex   sync.RWMutex
}

func (m *MockClassAware) GetClass() int8 {
	m.mutex.RLock()
	defer m.mutex.RUnlock()
	return m.classID
}

func (m *MockClassAware) SetClass(classID int8) {
	m.mutex.Lock()
	defer m.mutex.Unlock()
	m.classID = classID
}

type MockEntityWithClass struct {
	*MockClassAware
	id    int32
	name  string
	level int8
}

func (m *MockEntityWithClass) GetID() int32 {
	return m.id
}

func (m *MockEntityWithClass) GetName() string {
	return m.name
}

func (m *MockEntityWithClass) GetLevel() int8 {
	return m.level
}

func NewMockClassAware(classID int8) *MockClassAware {
	return &MockClassAware{classID: classID}
}

func NewMockEntityWithClass(id int32, name string, level int8, classID int8) *MockEntityWithClass {
	return &MockEntityWithClass{
		MockClassAware: NewMockClassAware(classID),
		id:             id,
		name:           name,
		level:          level,
	}
}

// Core Classes tests
func TestNewClasses(t *testing.T) {
	classes := NewClasses()
	if classes == nil {
		t.Fatal("NewClasses returned nil")
	}

	if len(classes.classMap) == 0 {
		t.Error("classMap should not be empty after initialization")
	}

	if len(classes.displayNameMap) == 0 {
		t.Error("displayNameMap should not be empty after initialization")
	}
}

func TestGetClassID(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		name           string
		input          string
		expectedID     int8
		shouldBeValid  bool
	}{
		{"Valid class name", "WARRIOR", ClassWarrior, true},
		{"Valid class name lowercase", "warrior", ClassWarrior, true},
		{"Valid class name with spaces", " WARRIOR ", ClassWarrior, true},
		{"Invalid class name", "INVALID", -1, false},
		{"Empty string", "", -1, false},
		{"Valid priest class", "CLERIC", ClassCleric, true},
		{"Valid mage class", "WIZARD", ClassWizard, true},
		{"Valid scout class", "RANGER", ClassRanger, true},
		{"Valid tradeskill class", "ARMORER", ClassArmorer, true},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := classes.GetClassID(tt.input)
			if tt.shouldBeValid {
				if result != tt.expectedID {
					t.Errorf("GetClassID(%s) = %d, want %d", tt.input, result, tt.expectedID)
				}
			} else {
				if result != -1 {
					t.Errorf("GetClassID(%s) should return -1 for invalid input, got %d", tt.input, result)
				}
			}
		})
	}
}

func TestGetClassName(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		classID      int8
		expectedName string
	}{
		{ClassWarrior, ClassNameWarrior},
		{ClassCleric, ClassNameCleric},
		{ClassWizard, ClassNameWizard},
		{ClassRanger, ClassNameRanger},
		{ClassArmorer, ClassNameArmorer},
		{-1, ""}, // Invalid class ID
		{100, ""}, // Invalid class ID
	}

	for _, tt := range tests {
		t.Run("GetClassName", func(t *testing.T) {
			result := classes.GetClassName(tt.classID)
			if result != tt.expectedName {
				t.Errorf("GetClassName(%d) = %s, want %s", tt.classID, result, tt.expectedName)
			}
		})
	}
}

func TestGetClassNameCase(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		classID          int8
		expectedDisplay  string
	}{
		{ClassWarrior, DisplayNameWarrior},
		{ClassCleric, DisplayNameCleric},
		{ClassWizard, DisplayNameWizard},
		{ClassRanger, DisplayNameRanger},
		{ClassArmorer, DisplayNameArmorer},
		{-1, ""}, // Invalid class ID
		{100, ""}, // Invalid class ID
	}

	for _, tt := range tests {
		t.Run("GetClassNameCase", func(t *testing.T) {
			result := classes.GetClassNameCase(tt.classID)
			if result != tt.expectedDisplay {
				t.Errorf("GetClassNameCase(%d) = %s, want %s", tt.classID, result, tt.expectedDisplay)
			}
		})
	}
}

func TestGetBaseClass(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		classID      int8
		expectedBase int8
	}{
		{ClassWarrior, ClassFighter},
		{ClassGuardian, ClassFighter},
		{ClassBerserker, ClassFighter},
		{ClassCleric, ClassPriest},
		{ClassTemplar, ClassPriest},
		{ClassWizard, ClassMage},
		{ClassWarlock, ClassMage},
		{ClassRanger, ClassScout},
		{ClassAssassin, ClassScout},
		{ClassShaper, ClassPriest},
		{ClassChanneler, ClassPriest},
		{ClassCommoner, ClassCommoner},
		{-1, ClassCommoner}, // Invalid defaults to Commoner
	}

	for _, tt := range tests {
		t.Run("GetBaseClass", func(t *testing.T) {
			result := classes.GetBaseClass(tt.classID)
			if result != tt.expectedBase {
				t.Errorf("GetBaseClass(%d) = %d, want %d", tt.classID, result, tt.expectedBase)
			}
		})
	}
}

func TestGetSecondaryBaseClass(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		classID              int8
		expectedSecondaryBase int8
	}{
		{ClassGuardian, ClassWarrior},
		{ClassBerserker, ClassWarrior},
		{ClassMonk, ClassBrawler},
		{ClassBruiser, ClassBrawler},
		{ClassShadowknight, ClassCrusader},
		{ClassPaladin, ClassCrusader},
		{ClassTemplar, ClassCleric},
		{ClassInquisitor, ClassCleric},
		{ClassWarden, ClassDruid},
		{ClassFury, ClassDruid},
		{ClassMystic, ClassShaman},
		{ClassDefiler, ClassShaman},
		{ClassWizard, ClassSorcerer},
		{ClassWarlock, ClassSorcerer},
		{ClassIllusionist, ClassEnchanter},
		{ClassCoercer, ClassEnchanter},
		{ClassConjuror, ClassSummoner},
		{ClassNecromancer, ClassSummoner},
		{ClassSwashbuckler, ClassRogue},
		{ClassBrigand, ClassRogue},
		{ClassTroubador, ClassBard},
		{ClassDirge, ClassBard},
		{ClassRanger, ClassPredator},
		{ClassAssassin, ClassPredator},
		{ClassBeastlord, ClassAnimalist},
		{ClassChanneler, ClassShaper},
		{ClassCommoner, ClassCommoner}, // Base classes return Commoner
		{ClassFighter, ClassCommoner},
	}

	for _, tt := range tests {
		t.Run("GetSecondaryBaseClass", func(t *testing.T) {
			result := classes.GetSecondaryBaseClass(tt.classID)
			if result != tt.expectedSecondaryBase {
				t.Errorf("GetSecondaryBaseClass(%d) = %d, want %d", tt.classID, result, tt.expectedSecondaryBase)
			}
		})
	}
}

func TestIsValidClassID(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		classID int8
		valid   bool
	}{
		{ClassCommoner, true},
		{ClassWarrior, true},
		{ClassAlchemist, true},
		{MinClassID, true},
		{MaxClassID, true},
		{-1, false},
		{MaxClassID + 1, false},
		{100, false},
	}

	for _, tt := range tests {
		t.Run("IsValidClassID", func(t *testing.T) {
			result := classes.IsValidClassID(tt.classID)
			if result != tt.valid {
				t.Errorf("IsValidClassID(%d) = %t, want %t", tt.classID, result, tt.valid)
			}
		})
	}
}

func TestGetAllClasses(t *testing.T) {
	classes := NewClasses()
	allClasses := classes.GetAllClasses()

	if len(allClasses) == 0 {
		t.Error("GetAllClasses should not return empty map")
	}

	// Check that all classes have valid display names
	for classID, displayName := range allClasses {
		if displayName == "" {
			t.Errorf("Class %d has empty display name", classID)
		}

		if !classes.IsValidClassID(classID) {
			t.Errorf("Invalid class ID in GetAllClasses: %d", classID)
		}
	}

	// Verify we have the expected number of classes
	expectedCount := MaxClasses
	if len(allClasses) != expectedCount {
		t.Errorf("GetAllClasses returned %d classes, expected %d", len(allClasses), expectedCount)
	}
}

func TestIsAdventureClass(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		classID   int8
		adventure bool
	}{
		{ClassCommoner, true},
		{ClassFighter, true},
		{ClassWarrior, true},
		{ClassChanneler, true},
		{ClassArtisan, false},
		{ClassCraftsman, false},
		{ClassAlchemist, false},
	}

	for _, tt := range tests {
		t.Run("IsAdventureClass", func(t *testing.T) {
			result := classes.IsAdventureClass(tt.classID)
			if result != tt.adventure {
				t.Errorf("IsAdventureClass(%d) = %t, want %t", tt.classID, result, tt.adventure)
			}
		})
	}
}

func TestIsTradeskillClass(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		classID    int8
		tradeskill bool
	}{
		{ClassCommoner, false},
		{ClassWarrior, false},
		{ClassChanneler, false},
		{ClassArtisan, true},
		{ClassCraftsman, true},
		{ClassAlchemist, true},
	}

	for _, tt := range tests {
		t.Run("IsTradeskillClass", func(t *testing.T) {
			result := classes.IsTradeskillClass(tt.classID)
			if result != tt.tradeskill {
				t.Errorf("IsTradeskillClass(%d) = %t, want %t", tt.classID, result, tt.tradeskill)
			}
		})
	}
}

func TestGetClassType(t *testing.T) {
	classes := NewClasses()

	tests := []struct {
		classID      int8
		expectedType string
	}{
		{ClassWarrior, ClassTypeAdventure},
		{ClassCleric, ClassTypeAdventure},
		{ClassChanneler, ClassTypeAdventure},
		{ClassArtisan, ClassTypeTradeskill},
		{ClassCraftsman, ClassTypeTradeskill},
		{ClassAlchemist, ClassTypeTradeskill},
		{-1, ClassTypeSpecial}, // Invalid class
		{100, ClassTypeSpecial}, // Invalid class
	}

	for _, tt := range tests {
		t.Run("GetClassType", func(t *testing.T) {
			result := classes.GetClassType(tt.classID)
			if result != tt.expectedType {
				t.Errorf("GetClassType(%d) = %s, want %s", tt.classID, result, tt.expectedType)
			}
		})
	}
}

func TestGetClassCount(t *testing.T) {
	classes := NewClasses()
	count := classes.GetClassCount()

	if count != MaxClasses {
		t.Errorf("GetClassCount() = %d, want %d", count, MaxClasses)
	}
}

func TestGetClassInfo(t *testing.T) {
	classes := NewClasses()

	// Test valid class
	info := classes.GetClassInfo(ClassWarrior)
	if !info["valid"].(bool) {
		t.Error("GetClassInfo should indicate valid class")
	}

	if info["class_id"] != ClassWarrior {
		t.Error("GetClassInfo should return correct class_id")
	}

	if info["name"] != ClassNameWarrior {
		t.Error("GetClassInfo should return correct name")
	}

	if info["display_name"] != DisplayNameWarrior {
		t.Error("GetClassInfo should return correct display_name")
	}

	// Test invalid class
	invalidInfo := classes.GetClassInfo(-1)
	if invalidInfo["valid"].(bool) {
		t.Error("GetClassInfo should indicate invalid class for -1")
	}
}

func TestGetGlobalClasses(t *testing.T) {
	classes1 := GetGlobalClasses()
	classes2 := GetGlobalClasses()

	if classes1 != classes2 {
		t.Error("GetGlobalClasses should return the same instance (singleton)")
	}

	if classes1 == nil {
		t.Error("GetGlobalClasses should not return nil")
	}
}

// ClassUtils tests
func TestNewClassUtils(t *testing.T) {
	utils := NewClassUtils()
	if utils == nil {
		t.Fatal("NewClassUtils returned nil")
	}

	if utils.classes == nil {
		t.Error("ClassUtils should have classes instance")
	}
}

func TestParseClassName(t *testing.T) {
	utils := NewClassUtils()

	tests := []struct {
		name     string
		input    string
		expected int8
	}{
		{"Exact match", "WARRIOR", ClassWarrior},
		{"Case insensitive", "warrior", ClassWarrior},
		{"With spaces", " Warrior ", ClassWarrior},
		{"With underscores", "SHADOW_KNIGHT", ClassShadowknight},
		{"With dashes", "SHADOW-KNIGHT", ClassShadowknight},
		{"Friendly name", "Warrior", ClassWarrior},
		{"Empty string", "", -1},
		{"Invalid name", "INVALID", -1},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := utils.ParseClassName(tt.input)
			if result != tt.expected {
				t.Errorf("ParseClassName(%s) = %d, want %d", tt.input, result, tt.expected)
			}
		})
	}
}

func TestFormatClassName(t *testing.T) {
	utils := NewClassUtils()

	tests := []struct {
		classID  int8
		format   string
		expected string
	}{
		{ClassWarrior, "display", DisplayNameWarrior},
		{ClassWarrior, "friendly", DisplayNameWarrior},
		{ClassWarrior, "upper", ClassNameWarrior},
		{ClassWarrior, "lowercase", strings.ToLower(ClassNameWarrior)},
		{ClassWarrior, "default", DisplayNameWarrior},
		{ClassWarrior, "", DisplayNameWarrior},
	}

	for _, tt := range tests {
		t.Run("FormatClassName", func(t *testing.T) {
			result := utils.FormatClassName(tt.classID, tt.format)
			if result != tt.expected {
				t.Errorf("FormatClassName(%d, %s) = %s, want %s", tt.classID, tt.format, result, tt.expected)
			}
		})
	}
}

func TestGetRandomClassByType(t *testing.T) {
	utils := NewClassUtils()

	// Test adventure classes
	adventureClass := utils.GetRandomClassByType(ClassTypeAdventure)
	classes := GetGlobalClasses()
	if !classes.IsAdventureClass(adventureClass) {
		t.Errorf("GetRandomClassByType(adventure) returned non-adventure class: %d", adventureClass)
	}

	// Test tradeskill classes
	tradeskillClass := utils.GetRandomClassByType(ClassTypeTradeskill)
	if !classes.IsTradeskillClass(tradeskillClass) {
		t.Errorf("GetRandomClassByType(tradeskill) returned non-tradeskill class: %d", tradeskillClass)
	}

	// Test invalid type
	invalidTypeClass := utils.GetRandomClassByType("invalid")
	if invalidTypeClass != DefaultClassID {
		t.Errorf("GetRandomClassByType(invalid) should return DefaultClassID, got %d", invalidTypeClass)
	}
}

func TestGetRandomAdventureClass(t *testing.T) {
	utils := NewClassUtils()
	classes := GetGlobalClasses()

	for i := 0; i < 10; i++ {
		adventureClass := utils.GetRandomAdventureClass()
		if !classes.IsAdventureClass(adventureClass) {
			t.Errorf("GetRandomAdventureClass() returned non-adventure class: %d", adventureClass)
		}
	}
}

func TestGetRandomTradeskillClass(t *testing.T) {
	utils := NewClassUtils()
	classes := GetGlobalClasses()

	for i := 0; i < 10; i++ {
		tradeskillClass := utils.GetRandomTradeskillClass()
		if !classes.IsTradeskillClass(tradeskillClass) {
			t.Errorf("GetRandomTradeskillClass() returned non-tradeskill class: %d", tradeskillClass)
		}
	}
}

func TestValidateClassForRace(t *testing.T) {
	utils := NewClassUtils()

	// Currently all classes are valid for all races
	if !utils.ValidateClassForRace(ClassWarrior, 1) {
		t.Error("ValidateClassForRace should return true for valid class")
	}

	if utils.ValidateClassForRace(-1, 1) {
		t.Error("ValidateClassForRace should return false for invalid class")
	}
}

func TestGetClassDescription(t *testing.T) {
	utils := NewClassUtils()

	description := utils.GetClassDescription(ClassWarrior)
	if description == "" {
		t.Error("GetClassDescription should return non-empty description for Warrior")
	}

	if !strings.Contains(strings.ToLower(description), "weapon") {
		t.Error("Warrior description should contain 'weapon'")
	}

	unknownDescription := utils.GetClassDescription(-1)
	if unknownDescription == "" {
		t.Error("GetClassDescription should return default description for invalid class")
	}
}

func TestGetClassProgression(t *testing.T) {
	utils := NewClassUtils()

	// Test final class progression
	guardianProgression := utils.GetClassProgression(ClassGuardian)
	expected := []int8{ClassCommoner, ClassFighter, ClassWarrior, ClassGuardian}
	
	if len(guardianProgression) != len(expected) {
		t.Errorf("Guardian progression length = %d, want %d", len(guardianProgression), len(expected))
	}

	for i, classID := range expected {
		if i < len(guardianProgression) && guardianProgression[i] != classID {
			t.Errorf("Guardian progression[%d] = %d, want %d", i, guardianProgression[i], classID)
		}
	}

	// Test base class progression (should be shorter)
	fighterProgression := utils.GetClassProgression(ClassFighter)
	if len(fighterProgression) >= len(guardianProgression) {
		t.Error("Fighter progression should be shorter than Guardian progression")
	}

	// Test commoner progression
	commonerProgression := utils.GetClassProgression(ClassCommoner)
	if len(commonerProgression) != 1 || commonerProgression[0] != ClassCommoner {
		t.Error("Commoner progression should only contain Commoner")
	}
}

func TestGetClassesForBaseClass(t *testing.T) {
	utils := NewClassUtils()

	fighterClasses := utils.GetClassesForBaseClass(ClassFighter)
	if len(fighterClasses) == 0 {
		t.Error("Should find fighter classes")
	}

	// Verify all returned classes have Fighter as base class
	classes := GetGlobalClasses()
	for _, classID := range fighterClasses {
		if classes.GetBaseClass(classID) != ClassFighter {
			t.Errorf("Class %d should have Fighter as base class", classID)
		}
	}
}

func TestGetClassesBySecondaryBase(t *testing.T) {
	utils := NewClassUtils()

	warriorClasses := utils.GetClassesBySecondaryBase(ClassWarrior)
	if len(warriorClasses) == 0 {
		t.Error("Should find classes with Warrior as secondary base")
	}

	// Verify all returned classes have Warrior as secondary base class
	classes := GetGlobalClasses()
	for _, classID := range warriorClasses {
		if classes.GetSecondaryBaseClass(classID) != ClassWarrior {
			t.Errorf("Class %d should have Warrior as secondary base class", classID)
		}
	}
}

func TestGetClassesByPattern(t *testing.T) {
	utils := NewClassUtils()

	// Search for classes containing "war"
	warClasses := utils.GetClassesByPattern("war")
	if len(warClasses) == 0 {
		t.Error("Should find classes matching 'war'")
	}

	// Verify matches
	classes := GetGlobalClasses()
	for _, classID := range warClasses {
		displayName := classes.GetClassNameCase(classID)
		if !strings.Contains(strings.ToLower(displayName), "war") {
			t.Errorf("Class %s should contain 'war'", displayName)
		}
	}

	// Test case insensitive search
	warClassesUpper := utils.GetClassesByPattern("WAR")
	if len(warClassesUpper) != len(warClasses) {
		t.Error("Pattern search should be case insensitive")
	}
}

func TestValidateClassTransition(t *testing.T) {
	utils := NewClassUtils()

	tests := []struct {
		name        string
		fromClass   int8
		toClass     int8
		shouldAllow bool
	}{
		{"Commoner to Fighter", ClassCommoner, ClassFighter, true},
		{"Fighter to Warrior", ClassFighter, ClassWarrior, true},
		{"Warrior to Guardian", ClassWarrior, ClassGuardian, true},
		{"Same class", ClassWarrior, ClassWarrior, false},
		{"Regression", ClassGuardian, ClassWarrior, false},
		{"Invalid from", -1, ClassWarrior, false},
		{"Invalid to", ClassWarrior, -1, false},
		{"Incompatible paths", ClassWarrior, ClassCleric, false},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			valid, _ := utils.ValidateClassTransition(tt.fromClass, tt.toClass)
			if valid != tt.shouldAllow {
				t.Errorf("ValidateClassTransition(%d, %d) = %t, want %t", tt.fromClass, tt.toClass, valid, tt.shouldAllow)
			}
		})
	}
}

func TestGetClassAliases(t *testing.T) {
	utils := NewClassUtils()

	// Test class with known aliases
	skAliases := utils.GetClassAliases(ClassShadowknight)
	if len(skAliases) == 0 {
		t.Error("Shadowknight should have aliases")
	}

	// Should contain the alias "SK"
	foundSK := false
	for _, alias := range skAliases {
		if alias == "SK" {
			foundSK = true
			break
		}
	}
	if !foundSK {
		t.Error("Shadowknight aliases should include 'SK'")
	}

	// Test class without specific aliases
	commonerAliases := utils.GetClassAliases(ClassCommoner)
	if len(commonerAliases) == 0 {
		t.Error("All classes should have at least their official names as aliases")
	}
}

func TestGetClassStatistics(t *testing.T) {
	utils := NewClassUtils()

	stats := utils.GetClassStatistics()

	if stats["total_classes"] == nil {
		t.Error("Statistics should include total_classes")
	}

	if stats["adventure_classes"] == nil {
		t.Error("Statistics should include adventure_classes")
	}

	if stats["tradeskill_classes"] == nil {
		t.Error("Statistics should include tradeskill_classes")
	}

	totalClasses := stats["total_classes"].(int)
	adventureClasses := stats["adventure_classes"].(int)
	tradeskillClasses := stats["tradeskill_classes"].(int)

	if totalClasses != adventureClasses + tradeskillClasses {
		t.Errorf("Total classes (%d) should equal adventure (%d) + tradeskill (%d)", 
			totalClasses, adventureClasses, tradeskillClasses)
	}
}

func TestFormatClassList(t *testing.T) {
	utils := NewClassUtils()

	classIDs := []int8{ClassWarrior, ClassCleric, ClassWizard}
	result := utils.FormatClassList(classIDs, ", ")

	expected := "Warrior, Cleric, Wizard"
	if result != expected {
		t.Errorf("FormatClassList() = %s, want %s", result, expected)
	}

	// Test empty list
	emptyResult := utils.FormatClassList([]int8{}, ", ")
	if emptyResult != "" {
		t.Error("FormatClassList with empty list should return empty string")
	}
}

func TestGetEQClassName(t *testing.T) {
	utils := NewClassUtils()

	// Currently just returns display name
	result := utils.GetEQClassName(ClassWarrior, 50)
	expected := DisplayNameWarrior
	if result != expected {
		t.Errorf("GetEQClassName() = %s, want %s", result, expected)
	}
}

func TestGetStartingClass(t *testing.T) {
	utils := NewClassUtils()

	startingClass := utils.GetStartingClass()
	if startingClass != ClassCommoner {
		t.Errorf("GetStartingClass() = %d, want %d", startingClass, ClassCommoner)
	}
}

func TestIsBaseClass(t *testing.T) {
	utils := NewClassUtils()

	tests := []struct {
		classID int8
		isBase  bool
	}{
		{ClassFighter, true},
		{ClassPriest, true},
		{ClassMage, true},
		{ClassScout, true},
		{ClassWarrior, false},
		{ClassCleric, false},
		{ClassCommoner, false},
	}

	for _, tt := range tests {
		t.Run("IsBaseClass", func(t *testing.T) {
			result := utils.IsBaseClass(tt.classID)
			if result != tt.isBase {
				t.Errorf("IsBaseClass(%d) = %t, want %t", tt.classID, result, tt.isBase)
			}
		})
	}
}

func TestIsSecondaryBaseClass(t *testing.T) {
	utils := NewClassUtils()

	// Warrior is a secondary base class (for Guardian, Berserker)
	if !utils.IsSecondaryBaseClass(ClassWarrior) {
		t.Error("Warrior should be a secondary base class")
	}

	// Guardian is not a secondary base class
	if utils.IsSecondaryBaseClass(ClassGuardian) {
		t.Error("Guardian should not be a secondary base class")
	}
}

// ClassIntegration tests
func TestNewClassIntegration(t *testing.T) {
	integration := NewClassIntegration()
	if integration == nil {
		t.Fatal("NewClassIntegration returned nil")
	}

	if integration.classes == nil {
		t.Error("ClassIntegration should have classes instance")
	}

	if integration.utils == nil {
		t.Error("ClassIntegration should have utils instance")
	}
}

func TestValidateEntityClass(t *testing.T) {
	integration := NewClassIntegration()

	// Test valid entity
	validEntity := NewMockClassAware(ClassWarrior)
	valid, message, info := integration.ValidateEntityClass(validEntity)

	if !valid {
		t.Error("ValidateEntityClass should return true for valid class")
	}

	if message != "Valid class" {
		t.Errorf("ValidateEntityClass message = %s, want 'Valid class'", message)
	}

	if info == nil {
		t.Error("ValidateEntityClass should return class info")
	}

	// Test invalid entity
	invalidEntity := NewMockClassAware(-1)
	valid, message, info = integration.ValidateEntityClass(invalidEntity)

	if valid {
		t.Error("ValidateEntityClass should return false for invalid class")
	}

	if info != nil {
		t.Error("ValidateEntityClass should return nil info for invalid class")
	}
}

func TestGetEntityClassInfo(t *testing.T) {
	integration := NewClassIntegration()

	entity := NewMockEntityWithClass(100, "TestEntity", 25, ClassWarrior)
	info := integration.GetEntityClassInfo(entity)

	if info["entity_id"] != int32(100) {
		t.Error("GetEntityClassInfo should include entity_id")
	}

	if info["entity_name"] != "TestEntity" {
		t.Error("GetEntityClassInfo should include entity_name")
	}

	if info["entity_level"] != int8(25) {
		t.Error("GetEntityClassInfo should include entity_level")
	}

	if info["class"] == nil {
		t.Error("GetEntityClassInfo should include class information")
	}

	if info["description"] == nil {
		t.Error("GetEntityClassInfo should include description")
	}
}

func TestChangeEntityClass(t *testing.T) {
	integration := NewClassIntegration()

	entity := NewMockClassAware(ClassCommoner)

	// Valid class change
	err := integration.ChangeEntityClass(entity, ClassFighter)
	if err != nil {
		t.Errorf("ChangeEntityClass should allow valid transition: %v", err)
	}

	if entity.GetClass() != ClassFighter {
		t.Error("Entity class should be updated after successful change")
	}

	// Invalid class change
	err = integration.ChangeEntityClass(entity, -1)
	if err == nil {
		t.Error("ChangeEntityClass should reject invalid class")
	}

	// Should not change class on error
	if entity.GetClass() != ClassFighter {
		t.Error("Entity class should not change on failed transition")
	}
}

func TestGetRandomClassForEntity(t *testing.T) {
	integration := NewClassIntegration()
	classes := GetGlobalClasses()

	adventureClass := integration.GetRandomClassForEntity(ClassTypeAdventure)
	if !classes.IsAdventureClass(adventureClass) {
		t.Error("GetRandomClassForEntity should return adventure class when requested")
	}

	tradeskillClass := integration.GetRandomClassForEntity(ClassTypeTradeskill)
	if !classes.IsTradeskillClass(tradeskillClass) {
		t.Error("GetRandomClassForEntity should return tradeskill class when requested")
	}
}

func TestCheckClassCompatibility(t *testing.T) {
	integration := NewClassIntegration()

	entity1 := NewMockClassAware(ClassWarrior)
	entity2 := NewMockClassAware(ClassCleric)

	// Currently all valid classes are compatible
	if !integration.CheckClassCompatibility(entity1, entity2) {
		t.Error("CheckClassCompatibility should return true for valid classes")
	}

	// Same class should be compatible
	entity3 := NewMockClassAware(ClassWarrior)
	if !integration.CheckClassCompatibility(entity1, entity3) {
		t.Error("CheckClassCompatibility should return true for same classes")
	}

	// Invalid class should not be compatible
	invalidEntity := NewMockClassAware(-1)
	if integration.CheckClassCompatibility(entity1, invalidEntity) {
		t.Error("CheckClassCompatibility should return false for invalid class")
	}
}

func TestFormatEntityClass(t *testing.T) {
	integration := NewClassIntegration()

	entity := NewMockEntityWithClass(100, "TestEntity", 25, ClassWarrior)

	// Test default format
	result := integration.FormatEntityClass(entity, "display")
	expected := DisplayNameWarrior
	if result != expected {
		t.Errorf("FormatEntityClass() = %s, want %s", result, expected)
	}

	// Test EQ format
	eqResult := integration.FormatEntityClass(entity, "eq")
	if eqResult == "" {
		t.Error("FormatEntityClass with eq format should not be empty")
	}
}

func TestGetEntityBaseClass(t *testing.T) {
	integration := NewClassIntegration()

	entity := NewMockClassAware(ClassWarrior)
	baseClass := integration.GetEntityBaseClass(entity)

	if baseClass != ClassFighter {
		t.Errorf("GetEntityBaseClass() = %d, want %d", baseClass, ClassFighter)
	}
}

func TestGetEntitySecondaryBaseClass(t *testing.T) {
	integration := NewClassIntegration()

	entity := NewMockClassAware(ClassGuardian)
	secondaryBase := integration.GetEntitySecondaryBaseClass(entity)

	if secondaryBase != ClassWarrior {
		t.Errorf("GetEntitySecondaryBaseClass() = %d, want %d", secondaryBase, ClassWarrior)
	}
}

func TestIsEntityAdventureClass(t *testing.T) {
	integration := NewClassIntegration()

	adventureEntity := NewMockClassAware(ClassWarrior)
	if !integration.IsEntityAdventureClass(adventureEntity) {
		t.Error("IsEntityAdventureClass should return true for adventure class")
	}

	tradeskillEntity := NewMockClassAware(ClassArmorer)
	if integration.IsEntityAdventureClass(tradeskillEntity) {
		t.Error("IsEntityAdventureClass should return false for tradeskill class")
	}
}

func TestIsEntityTradeskillClass(t *testing.T) {
	integration := NewClassIntegration()

	tradeskillEntity := NewMockClassAware(ClassArmorer)
	if !integration.IsEntityTradeskillClass(tradeskillEntity) {
		t.Error("IsEntityTradeskillClass should return true for tradeskill class")
	}

	adventureEntity := NewMockClassAware(ClassWarrior)
	if integration.IsEntityTradeskillClass(adventureEntity) {
		t.Error("IsEntityTradeskillClass should return false for adventure class")
	}
}

func TestGetEntitiesByClass(t *testing.T) {
	integration := NewClassIntegration()

	entities := []ClassAware{
		NewMockClassAware(ClassWarrior),
		NewMockClassAware(ClassCleric),
		NewMockClassAware(ClassWarrior),
		NewMockClassAware(ClassWizard),
	}

	warriors := integration.GetEntitiesByClass(entities, ClassWarrior)
	if len(warriors) != 2 {
		t.Errorf("GetEntitiesByClass should find 2 warriors, found %d", len(warriors))
	}

	clerics := integration.GetEntitiesByClass(entities, ClassCleric)
	if len(clerics) != 1 {
		t.Errorf("GetEntitiesByClass should find 1 cleric, found %d", len(clerics))
	}
}

func TestGetEntitiesByBaseClass(t *testing.T) {
	integration := NewClassIntegration()

	entities := []ClassAware{
		NewMockClassAware(ClassWarrior),    // Fighter base
		NewMockClassAware(ClassGuardian),   // Fighter base
		NewMockClassAware(ClassCleric),     // Priest base
		NewMockClassAware(ClassWizard),     // Mage base
	}

	fighters := integration.GetEntitiesByBaseClass(entities, ClassFighter)
	if len(fighters) != 2 {
		t.Errorf("GetEntitiesByBaseClass should find 2 fighters, found %d", len(fighters))
	}
}

func TestGetEntitiesByClassType(t *testing.T) {
	integration := NewClassIntegration()

	entities := []ClassAware{
		NewMockClassAware(ClassWarrior),    // Adventure
		NewMockClassAware(ClassCleric),     // Adventure
		NewMockClassAware(ClassArmorer),    // Tradeskill
		NewMockClassAware(ClassAlchemist),  // Tradeskill
	}

	adventurers := integration.GetEntitiesByClassType(entities, ClassTypeAdventure)
	if len(adventurers) != 2 {
		t.Errorf("GetEntitiesByClassType should find 2 adventure classes, found %d", len(adventurers))
	}

	crafters := integration.GetEntitiesByClassType(entities, ClassTypeTradeskill)
	if len(crafters) != 2 {
		t.Errorf("GetEntitiesByClassType should find 2 tradeskill classes, found %d", len(crafters))
	}
}

func TestIntegrationValidateClassForRace(t *testing.T) {
	integration := NewClassIntegration()

	// Valid class and race
	valid, message := integration.ValidateClassForRace(ClassWarrior, 1)
	if !valid {
		t.Error("ValidateClassForRace should return true for valid class")
	}
	if message != "" {
		t.Error("ValidateClassForRace should return empty message for valid combination")
	}

	// Invalid class
	valid, message = integration.ValidateClassForRace(-1, 1)
	if valid {
		t.Error("ValidateClassForRace should return false for invalid class")
	}
	if message == "" {
		t.Error("ValidateClassForRace should return error message for invalid class")
	}
}

func TestGetClassStartingStats(t *testing.T) {
	integration := NewClassIntegration()

	// Test fighter class stats
	fighterStats := integration.GetClassStartingStats(ClassWarrior)
	if len(fighterStats) == 0 {
		t.Error("GetClassStartingStats should return stats")
	}

	// Fighters should have bonus strength
	if fighterStats["strength"] <= 50 {
		t.Error("Fighters should have strength bonus")
	}

	// Test priest class stats
	priestStats := integration.GetClassStartingStats(ClassCleric)
	if priestStats["wisdom"] <= 50 {
		t.Error("Priests should have wisdom bonus")
	}

	// Test mage class stats
	mageStats := integration.GetClassStartingStats(ClassWizard)
	if mageStats["intelligence"] <= 50 {
		t.Error("Mages should have intelligence bonus")
	}

	// Test scout class stats
	scoutStats := integration.GetClassStartingStats(ClassRanger)
	if scoutStats["agility"] <= 50 {
		t.Error("Scouts should have agility bonus")
	}
}

func TestCreateClassSpecificEntity(t *testing.T) {
	integration := NewClassIntegration()

	entityData := integration.CreateClassSpecificEntity(ClassWarrior)
	if entityData == nil {
		t.Fatal("CreateClassSpecificEntity should not return nil for valid class")
	}

	if entityData["class_id"] != ClassWarrior {
		t.Errorf("Entity data class_id = %v, want %v", entityData["class_id"], ClassWarrior)
	}

	if entityData["class_name"] != DisplayNameWarrior {
		t.Error("Entity data should include correct class_name")
	}

	if entityData["starting_stats"] == nil {
		t.Error("Entity data should include starting_stats")
	}

	if entityData["progression"] == nil {
		t.Error("Entity data should include progression")
	}

	// Test invalid class
	invalidData := integration.CreateClassSpecificEntity(-1)
	if invalidData != nil {
		t.Error("CreateClassSpecificEntity should return nil for invalid class")
	}
}

func TestGetClassSelectionData(t *testing.T) {
	integration := NewClassIntegration()

	selectionData := integration.GetClassSelectionData()
	if selectionData == nil {
		t.Fatal("GetClassSelectionData should not return nil")
	}

	if selectionData["adventure_classes"] == nil {
		t.Error("Selection data should include adventure_classes")
	}

	if selectionData["statistics"] == nil {
		t.Error("Selection data should include statistics")
	}

	adventureClasses := selectionData["adventure_classes"].([]map[string]interface{})
	if len(adventureClasses) == 0 {
		t.Error("Selection data should include adventure classes")
	}

	// Verify no tradeskill classes in selection
	for _, classData := range adventureClasses {
		classType := classData["type"].(string)
		if classType != ClassTypeAdventure {
			t.Error("Class selection should only include adventure classes")
		}
	}
}

func TestGetGlobalClassIntegration(t *testing.T) {
	integration1 := GetGlobalClassIntegration()
	integration2 := GetGlobalClassIntegration()

	if integration1 != integration2 {
		t.Error("GetGlobalClassIntegration should return the same instance")
	}

	if integration1 == nil {
		t.Error("GetGlobalClassIntegration should not return nil")
	}
}

// ClassManager tests
func TestNewClassManager(t *testing.T) {
	manager := NewClassManager()
	if manager == nil {
		t.Fatal("NewClassManager returned nil")
	}

	if manager.classes == nil {
		t.Error("ClassManager should have classes instance")
	}

	if manager.utils == nil {
		t.Error("ClassManager should have utils instance")
	}

	if manager.integration == nil {
		t.Error("ClassManager should have integration instance")
	}

	if manager.classUsageStats == nil {
		t.Error("ClassManager should initialize usage stats")
	}
}

func TestRegisterClassUsage(t *testing.T) {
	manager := NewClassManager()

	// Register usage for valid class
	manager.RegisterClassUsage(ClassWarrior)
	
	stats := manager.GetClassUsageStats()
	if stats[ClassWarrior] != 1 {
		t.Errorf("Usage count for Warrior should be 1, got %d", stats[ClassWarrior])
	}

	// Register more usage
	manager.RegisterClassUsage(ClassWarrior)
	manager.RegisterClassUsage(ClassCleric)

	stats = manager.GetClassUsageStats()
	if stats[ClassWarrior] != 2 {
		t.Errorf("Usage count for Warrior should be 2, got %d", stats[ClassWarrior])
	}
	if stats[ClassCleric] != 1 {
		t.Errorf("Usage count for Cleric should be 1, got %d", stats[ClassCleric])
	}

	// Register usage for invalid class (should be ignored)
	manager.RegisterClassUsage(-1)
	stats = manager.GetClassUsageStats()
	if _, exists := stats[-1]; exists {
		t.Error("Invalid class usage should not be registered")
	}
}

func TestGetMostPopularClass(t *testing.T) {
	manager := NewClassManager()

	// No usage yet
	mostPopular, maxUsage := manager.GetMostPopularClass()
	if mostPopular != -1 || maxUsage != 0 {
		t.Error("Most popular class should be -1 with 0 usage when no usage recorded")
	}

	// Register some usage
	manager.RegisterClassUsage(ClassWarrior)
	manager.RegisterClassUsage(ClassWarrior)
	manager.RegisterClassUsage(ClassCleric)

	mostPopular, maxUsage = manager.GetMostPopularClass()
	if mostPopular != ClassWarrior || maxUsage != 2 {
		t.Errorf("Most popular should be Warrior with 2 usage, got class %d with %d usage", mostPopular, maxUsage)
	}
}

func TestGetLeastPopularClass(t *testing.T) {
	manager := NewClassManager()

	// No usage yet
	leastPopular, minUsage := manager.GetLeastPopularClass()
	if leastPopular != -1 || minUsage != -1 {
		t.Error("Least popular class should be -1 with -1 usage when no usage recorded")
	}

	// Register some usage
	manager.RegisterClassUsage(ClassWarrior)
	manager.RegisterClassUsage(ClassWarrior)
	manager.RegisterClassUsage(ClassCleric)

	leastPopular, minUsage = manager.GetLeastPopularClass()
	if leastPopular != ClassCleric || minUsage != 1 {
		t.Errorf("Least popular should be Cleric with 1 usage, got class %d with %d usage", leastPopular, minUsage)
	}
}

func TestResetUsageStats(t *testing.T) {
	manager := NewClassManager()

	// Register some usage
	manager.RegisterClassUsage(ClassWarrior)
	manager.RegisterClassUsage(ClassCleric)

	stats := manager.GetClassUsageStats()
	if len(stats) == 0 {
		t.Error("Should have usage stats before reset")
	}

	// Reset stats
	manager.ResetUsageStats()

	stats = manager.GetClassUsageStats()
	if len(stats) != 0 {
		t.Error("Usage stats should be empty after reset")
	}
}

func TestProcessClassCommand(t *testing.T) {
	manager := NewClassManager()

	// Test list command
	result, err := manager.ProcessClassCommand("list", []string{})
	if err != nil {
		t.Errorf("List command should not error: %v", err)
	}
	if result == "" {
		t.Error("List command should return results")
	}

	// Test info command with valid class
	result, err = manager.ProcessClassCommand("info", []string{"WARRIOR"})
	if err != nil {
		t.Errorf("Info command should not error: %v", err)
	}
	if result == "" {
		t.Error("Info command should return results")
	}

	// Test info command without args
	_, err = manager.ProcessClassCommand("info", []string{})
	if err == nil {
		t.Error("Info command without args should error")
	}

	// Test random command
	result, err = manager.ProcessClassCommand("random", []string{})
	if err != nil {
		t.Errorf("Random command should not error: %v", err)
	}
	if result == "" {
		t.Error("Random command should return results")
	}

	// Test stats command
	result, err = manager.ProcessClassCommand("stats", []string{})
	if err != nil {
		t.Errorf("Stats command should not error: %v", err)
	}
	if result == "" {
		t.Error("Stats command should return results")
	}

	// Test search command with pattern
	result, err = manager.ProcessClassCommand("search", []string{"war"})
	if err != nil {
		t.Errorf("Search command should not error: %v", err)
	}
	if result == "" {
		t.Error("Search command should return results")
	}

	// Test search command without args
	_, err = manager.ProcessClassCommand("search", []string{})
	if err == nil {
		t.Error("Search command without args should error")
	}

	// Test progression command
	result, err = manager.ProcessClassCommand("progression", []string{"GUARDIAN"})
	if err != nil {
		t.Errorf("Progression command should not error: %v", err)
	}
	if result == "" {
		t.Error("Progression command should return results")
	}

	// Test unknown command
	_, err = manager.ProcessClassCommand("unknown", []string{})
	if err == nil {
		t.Error("Unknown command should error")
	}
}

func TestValidateEntityClasses(t *testing.T) {
	manager := NewClassManager()

	entities := []ClassAware{
		NewMockClassAware(ClassWarrior),
		NewMockClassAware(ClassCleric),
		NewMockClassAware(-1), // Invalid
		NewMockClassAware(ClassWizard),
		NewMockClassAware(100), // Invalid
	}

	results := manager.ValidateEntityClasses(entities)

	if results["total_entities"] != len(entities) {
		t.Error("Validation results should include total entity count")
	}

	if results["valid_count"] != 3 {
		t.Errorf("Should find 3 valid entities, found %v", results["valid_count"])
	}

	if results["invalid_count"] != 2 {
		t.Errorf("Should find 2 invalid entities, found %v", results["invalid_count"])
	}

	if results["class_distribution"] == nil {
		t.Error("Validation results should include class distribution")
	}

	if results["invalid_entities"] == nil {
		t.Error("Validation results should include invalid entities list")
	}
}

func TestGetClassRecommendations(t *testing.T) {
	manager := NewClassManager()

	// Test recommendations by class type
	preferences := map[string]interface{}{
		"class_type": ClassTypeAdventure,
	}

	recommendations := manager.GetClassRecommendations(preferences)
	if len(recommendations) == 0 {
		t.Error("Should get recommendations for adventure classes")
	}

	classes := GetGlobalClasses()
	for _, classID := range recommendations {
		if !classes.IsAdventureClass(classID) {
			t.Error("Adventure class recommendations should only include adventure classes")
		}
	}

	// Test recommendations by base class
	basePreferences := map[string]interface{}{
		"base_class": ClassFighter,
	}

	baseRecommendations := manager.GetClassRecommendations(basePreferences)
	if len(baseRecommendations) == 0 {
		t.Error("Should get recommendations for fighter base class")
	}

	// Test recommendations by preferred stats
	statPreferences := map[string]interface{}{
		"preferred_stats": []string{"strength", "stamina"},
	}

	statRecommendations := manager.GetClassRecommendations(statPreferences)
	if len(statRecommendations) == 0 {
		t.Error("Should get recommendations for preferred stats")
	}

	// Test empty preferences (should get defaults)
	emptyPreferences := map[string]interface{}{}
	defaultRecommendations := manager.GetClassRecommendations(emptyPreferences)
	if len(defaultRecommendations) == 0 {
		t.Error("Should get default recommendations when no preferences given")
	}
}

func TestGetGlobalClassManager(t *testing.T) {
	manager1 := GetGlobalClassManager()
	manager2 := GetGlobalClassManager()

	if manager1 != manager2 {
		t.Error("GetGlobalClassManager should return the same instance (singleton)")
	}

	if manager1 == nil {
		t.Error("GetGlobalClassManager should not return nil")
	}
}

// Constants tests
func TestClassConstants(t *testing.T) {
	// Test class ID constants
	if ClassCommoner != 0 {
		t.Errorf("ClassCommoner = %d, want 0", ClassCommoner)
	}

	if ClassFighter != 1 {
		t.Errorf("ClassFighter = %d, want 1", ClassFighter)
	}

	if ClassAlchemist != 57 {
		t.Errorf("ClassAlchemist = %d, want 57", ClassAlchemist)
	}

	// Test validation constants
	if MinClassID != 0 {
		t.Errorf("MinClassID = %d, want 0", MinClassID)
	}

	if MaxClassID != 57 {
		t.Errorf("MaxClassID = %d, want 57", MaxClassID)
	}

	if MaxClasses != 58 {
		t.Errorf("MaxClasses = %d, want 58", MaxClasses)
	}

	// Test class type constants
	if ClassTypeAdventure != "adventure" {
		t.Errorf("ClassTypeAdventure = %s, want adventure", ClassTypeAdventure)
	}

	if ClassTypeTradeskill != "tradeskill" {
		t.Errorf("ClassTypeTradeskill = %s, want tradeskill", ClassTypeTradeskill)
	}
}

// Concurrency tests
func TestClassesConcurrency(t *testing.T) {
	classes := NewClasses()
	var wg sync.WaitGroup

	// Concurrent reads
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(classID int8) {
			defer wg.Done()
			classes.GetClassName(classID)
			classes.GetClassNameCase(classID)
			classes.GetBaseClass(classID)
			classes.IsValidClassID(classID)
			classes.GetAllClasses()
		}(int8(i % MaxClasses))
	}

	wg.Wait()

	// Verify state consistency after concurrent access
	allClasses := classes.GetAllClasses()
	if len(allClasses) != MaxClasses {
		t.Error("Concurrent access should not affect class data integrity")
	}
}

func TestClassManagerConcurrency(t *testing.T) {
	manager := NewClassManager()
	var wg sync.WaitGroup

	// Concurrent usage registration
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(classID int8) {
			defer wg.Done()
			manager.RegisterClassUsage(classID)
		}(int8(i % 10)) // Use first 10 classes
	}

	// Concurrent stats reading
	for i := 0; i < 50; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			manager.GetClassUsageStats()
			manager.GetMostPopularClass()
			manager.GetLeastPopularClass()
		}()
	}

	wg.Wait()

	// Verify final state
	stats := manager.GetClassUsageStats()
	totalUsage := int32(0)
	for _, count := range stats {
		totalUsage += count
	}

	if totalUsage != 100 {
		t.Errorf("Total usage should be 100, got %d", totalUsage)
	}
}

func TestMockEntitiesConcurrency(t *testing.T) {
	entity := NewMockClassAware(ClassWarrior)
	var wg sync.WaitGroup

	// Concurrent reads and writes
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(classID int8) {
			defer wg.Done()
			entity.SetClass(classID)
			entity.GetClass()
		}(int8(i % MaxClasses))
	}

	wg.Wait()

	// Entity should have a valid class after concurrent access
	finalClass := entity.GetClass()
	classes := GetGlobalClasses()
	if !classes.IsValidClassID(finalClass) {
		t.Errorf("Final class %d should be valid after concurrent access", finalClass)
	}
}

// Benchmarks
func BenchmarkGetClassID(b *testing.B) {
	classes := NewClasses()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		classes.GetClassID("WARRIOR")
	}
}

func BenchmarkGetClassName(b *testing.B) {
	classes := NewClasses()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		classes.GetClassName(ClassWarrior)
	}
}

func BenchmarkGetBaseClass(b *testing.B) {
	classes := NewClasses()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		classes.GetBaseClass(ClassGuardian)
	}
}

func BenchmarkGetAllClasses(b *testing.B) {
	classes := NewClasses()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		classes.GetAllClasses()
	}
}

func BenchmarkParseClassName(b *testing.B) {
	utils := NewClassUtils()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		utils.ParseClassName("WARRIOR")
	}
}

func BenchmarkGetRandomClassByType(b *testing.B) {
	utils := NewClassUtils()
	rand.Seed(time.Now().UnixNano())
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		utils.GetRandomClassByType(ClassTypeAdventure)
	}
}

func BenchmarkRegisterClassUsage(b *testing.B) {
	manager := NewClassManager()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		manager.RegisterClassUsage(ClassWarrior)
	}
}

func BenchmarkValidateEntityClass(b *testing.B) {
	integration := NewClassIntegration()
	entity := NewMockClassAware(ClassWarrior)
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		integration.ValidateEntityClass(entity)
	}
}

func BenchmarkMockClassAwareGetSet(b *testing.B) {
	entity := NewMockClassAware(ClassWarrior)
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		entity.SetClass(ClassCleric)
		entity.GetClass()
	}
}