package engine

import (
	"context"
	"testing"
)

// TestSelectColors_EmptyColors tests the defensive check for empty available colors
func TestSelectColors_EmptyColors(t *testing.T) {
	// Create a generator for testing
	generator, err := NewDefaultGenerator()
	if err != nil {
		t.Fatalf("Failed to create generator: %v", err)
	}

	// Test with empty available colors slice
	hash := "1234567890abcdef"
	emptyColors := []Color{}

	_, err = generator.selectColors(hash, emptyColors)
	if err == nil {
		t.Fatal("expected error for empty available colors, got nil")
	}

	expectedMsg := "no available colors"
	if !contains(err.Error(), expectedMsg) {
		t.Errorf("expected error message to contain %q, got %q", expectedMsg, err.Error())
	}

	t.Logf("Got expected error: %v", err)
}

// TestSelectColors_ValidColors tests that selectColors works correctly with valid input
func TestSelectColors_ValidColors(t *testing.T) {
	// Create a generator for testing
	generator, err := NewDefaultGenerator()
	if err != nil {
		t.Fatalf("Failed to create generator: %v", err)
	}

	// Create a sample set of colors (similar to what GenerateColorTheme returns)
	config := DefaultColorConfig()
	availableColors := GenerateColorTheme(0.5, config)

	if len(availableColors) == 0 {
		t.Fatal("GenerateColorTheme returned empty colors")
	}

	hash := "1234567890abcdef"
	selectedIndexes, err := generator.selectColors(hash, availableColors)
	if err != nil {
		t.Fatalf("selectColors failed with valid input: %v", err)
	}

	// Should return exactly numColorSelections (3) color indexes
	if len(selectedIndexes) != numColorSelections {
		t.Errorf("expected %d selected colors, got %d", numColorSelections, len(selectedIndexes))
	}

	// All indexes should be valid (within bounds of available colors)
	for i, index := range selectedIndexes {
		if index < 0 || index >= len(availableColors) {
			t.Errorf("selected index %d at position %d is out of bounds (0-%d)", index, i, len(availableColors)-1)
		}
	}
}

// TestGenerator_GenerateIcon_RobustnessChecks tests that generateIcon handles edge cases gracefully
func TestGenerator_GenerateIcon_RobustnessChecks(t *testing.T) {
	generator, err := NewDefaultGenerator()
	if err != nil {
		t.Fatalf("Failed to create generator: %v", err)
	}

	testCases := []struct {
		name        string
		hash        string
		size        float64
		expectError bool
	}{
		{"valid_input", "1234567890abcdef12345", 64.0, false},
		{"minimum_size", "1234567890abcdef12345", 1.0, false},
		{"large_size", "1234567890abcdef12345", 1024.0, false},
		{"zero_size", "1234567890abcdef12345", 0.0, false},       // generateIcon doesn't validate size
		{"negative_size", "1234567890abcdef12345", -10.0, false}, // generateIcon doesn't validate size
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			icon, err := generator.generateIcon(context.Background(), tc.hash, tc.size)

			if tc.expectError {
				if err == nil {
					t.Errorf("expected error for %s, got none", tc.name)
				}
			} else {
				if err != nil {
					t.Errorf("unexpected error for %s: %v", tc.name, err)
				}

				if icon == nil {
					t.Errorf("got nil icon for valid input %s", tc.name)
				}

				// Validate icon properties
				if icon != nil {
					if icon.Size != tc.size {
						t.Errorf("icon size mismatch: expected %f, got %f", tc.size, icon.Size)
					}

					if icon.Hash != tc.hash {
						t.Errorf("icon hash mismatch: expected %s, got %s", tc.hash, icon.Hash)
					}
				}
			}
		})
	}
}

// TestHueExtraction_EdgeCases tests hue extraction with edge case inputs
func TestHueExtraction_EdgeCases(t *testing.T) {
	generator, err := NewDefaultGenerator()
	if err != nil {
		t.Fatalf("Failed to create generator: %v", err)
	}

	testCases := []struct {
		name        string
		hash        string
		expectError bool
	}{
		{"valid_hash", "1234567890abcdef12345", false},
		{"minimum_length", "1234567890a", false}, // Exactly 11 characters
		{"hex_only", "abcdefabcdefabcdef123", false},
		{"numbers_only", "12345678901234567890", false},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			hue, err := generator.extractHue(tc.hash)

			if tc.expectError {
				if err == nil {
					t.Errorf("expected error for %s, got none", tc.name)
				}
			} else {
				if err != nil {
					t.Errorf("unexpected error for %s: %v", tc.name, err)
				}

				// Hue should be in range [0, 1]
				if hue < 0 || hue > 1 {
					t.Errorf("hue out of range for %s: %f (should be 0-1)", tc.name, hue)
				}
			}
		})
	}
}

// Helper function to check if a string contains a substring (defined in color_graceful_degradation_test.go)
