package services

import (
	"regexp"
	"strings"
	"testing"

	"github.com/breakpilot/consent-service/internal/models"
)

// ========================================
// Test All 19 Email Categories
// ========================================

// TestEmailTemplateService_GetDefaultTemplateContent tests default content generation for each email type
func TestEmailTemplateService_GetDefaultTemplateContent(t *testing.T) {
	service := &EmailTemplateService{}

	// All 19 email categories
	tests := []struct {
		name         string
		emailType    string
		language     string
		wantSubject  bool
		wantBodyHTML bool
		wantBodyText bool
	}{
		// Auth Lifecycle (10 types)
		{"welcome_de", models.EmailTypeWelcome, "de", true, true, true},
		{"email_verification_de", models.EmailTypeEmailVerification, "de", true, true, true},
		{"password_reset_de", models.EmailTypePasswordReset, "de", true, true, true},
		{"password_changed_de", models.EmailTypePasswordChanged, "de", true, true, true},
		{"2fa_enabled_de", models.EmailType2FAEnabled, "de", true, true, true},
		{"2fa_disabled_de", models.EmailType2FADisabled, "de", true, true, true},
		{"new_device_login_de", models.EmailTypeNewDeviceLogin, "de", true, true, true},
		{"suspicious_activity_de", models.EmailTypeSuspiciousActivity, "de", true, true, true},
		{"account_locked_de", models.EmailTypeAccountLocked, "de", true, true, true},
		{"account_unlocked_de", models.EmailTypeAccountUnlocked, "de", true, true, true},

		// GDPR/Privacy (5 types)
		{"deletion_requested_de", models.EmailTypeDeletionRequested, "de", true, true, true},
		{"deletion_confirmed_de", models.EmailTypeDeletionConfirmed, "de", true, true, true},
		{"data_export_ready_de", models.EmailTypeDataExportReady, "de", true, true, true},
		{"email_changed_de", models.EmailTypeEmailChanged, "de", true, true, true},
		{"email_change_verify_de", models.EmailTypeEmailChangeVerify, "de", true, true, true},

		// Consent Management (4 types)
		{"new_version_published_de", models.EmailTypeNewVersionPublished, "de", true, true, true},
		{"consent_reminder_de", models.EmailTypeConsentReminder, "de", true, true, true},
		{"consent_deadline_warning_de", models.EmailTypeConsentDeadlineWarning, "de", true, true, true},
		{"account_suspended_de", models.EmailTypeAccountSuspended, "de", true, true, true},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			subject, bodyHTML, bodyText := service.GetDefaultTemplateContent(tt.emailType, tt.language)

			if tt.wantSubject && subject == "" {
				t.Errorf("GetDefaultTemplateContent(%s, %s): expected subject, got empty string", tt.emailType, tt.language)
			}
			if tt.wantBodyHTML && bodyHTML == "" {
				t.Errorf("GetDefaultTemplateContent(%s, %s): expected bodyHTML, got empty string", tt.emailType, tt.language)
			}
			if tt.wantBodyText && bodyText == "" {
				t.Errorf("GetDefaultTemplateContent(%s, %s): expected bodyText, got empty string", tt.emailType, tt.language)
			}
		})
	}
}

// TestEmailTemplateService_GetDefaultTemplateContent_UnknownType tests default content for unknown type
func TestEmailTemplateService_GetDefaultTemplateContent_UnknownType(t *testing.T) {
	service := &EmailTemplateService{}

	subject, bodyHTML, bodyText := service.GetDefaultTemplateContent("unknown_type", "de")

	// The service returns a fallback for unknown types
	if subject == "" {
		t.Errorf("GetDefaultTemplateContent(unknown_type, de): expected fallback subject, got empty")
	}
	if bodyHTML == "" {
		t.Errorf("GetDefaultTemplateContent(unknown_type, de): expected fallback bodyHTML, got empty")
	}
	if bodyText == "" {
		t.Errorf("GetDefaultTemplateContent(unknown_type, de): expected fallback bodyText, got empty")
	}
}

// TestEmailTemplateService_GetDefaultTemplateContent_UnsupportedLanguage tests fallback for unsupported language
func TestEmailTemplateService_GetDefaultTemplateContent_UnsupportedLanguage(t *testing.T) {
	service := &EmailTemplateService{}

	// Test with unsupported language - should return fallback
	subject, bodyHTML, bodyText := service.GetDefaultTemplateContent(models.EmailTypeWelcome, "fr")

	// Should return fallback (not empty, but generic)
	if subject == "" || bodyHTML == "" || bodyText == "" {
		t.Error("GetDefaultTemplateContent should return fallback for unsupported language")
	}
}

// TestReplaceVariables tests variable replacement in templates
func TestReplaceVariables(t *testing.T) {
	tests := []struct {
		name      string
		template  string
		variables map[string]string
		expected  string
	}{
		{
			name:      "single variable",
			template:  "Hallo {{user_name}}!",
			variables: map[string]string{"user_name": "Max"},
			expected:  "Hallo Max!",
		},
		{
			name:      "multiple variables",
			template:  "Hallo {{user_name}}, klicken Sie hier: {{reset_link}}",
			variables: map[string]string{"user_name": "Max", "reset_link": "https://example.com"},
			expected:  "Hallo Max, klicken Sie hier: https://example.com",
		},
		{
			name:      "no variables",
			template:  "Hallo Welt!",
			variables: map[string]string{},
			expected:  "Hallo Welt!",
		},
		{
			name:      "missing variable - not replaced",
			template:  "Hallo {{user_name}} und {{missing}}!",
			variables: map[string]string{"user_name": "Max"},
			expected:  "Hallo Max und {{missing}}!",
		},
		{
			name:      "empty template",
			template:  "",
			variables: map[string]string{"user_name": "Max"},
			expected:  "",
		},
		{
			name:      "variable with special characters",
			template:  "IP: {{ip_address}}",
			variables: map[string]string{"ip_address": "192.168.1.1"},
			expected:  "IP: 192.168.1.1",
		},
		{
			name:      "variable with URL",
			template:  "Link: {{verification_url}}",
			variables: map[string]string{"verification_url": "https://example.com/verify?token=abc123&user=test"},
			expected:  "Link: https://example.com/verify?token=abc123&user=test",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := testReplaceVariables(tt.template, tt.variables)
			if result != tt.expected {
				t.Errorf("replaceVariables() = %s, want %s", result, tt.expected)
			}
		})
	}
}

// testReplaceVariables is a test helper function for variable replacement
func testReplaceVariables(template string, variables map[string]string) string {
	result := template
	for key, value := range variables {
		placeholder := "{{" + key + "}}"
		for i := 0; i < len(result); i++ {
			idx := testFindSubstring(result, placeholder)
			if idx == -1 {
				break
			}
			result = result[:idx] + value + result[idx+len(placeholder):]
		}
	}
	return result
}

func testFindSubstring(s, substr string) int {
	for i := 0; i <= len(s)-len(substr); i++ {
		if s[i:i+len(substr)] == substr {
			return i
		}
	}
	return -1
}

// TestEmailTypeConstantsExist verifies that all expected email types are defined
func TestEmailTypeConstantsExist(t *testing.T) {
	// Test that all 19 email type constants are defined and produce non-empty templates
	types := []string{
		// Auth Lifecycle
		models.EmailTypeWelcome,
		models.EmailTypeEmailVerification,
		models.EmailTypePasswordReset,
		models.EmailTypePasswordChanged,
		models.EmailType2FAEnabled,
		models.EmailType2FADisabled,
		models.EmailTypeNewDeviceLogin,
		models.EmailTypeSuspiciousActivity,
		models.EmailTypeAccountLocked,
		models.EmailTypeAccountUnlocked,
		// GDPR/Privacy
		models.EmailTypeDeletionRequested,
		models.EmailTypeDeletionConfirmed,
		models.EmailTypeDataExportReady,
		models.EmailTypeEmailChanged,
		models.EmailTypeEmailChangeVerify,
		// Consent Management
		models.EmailTypeNewVersionPublished,
		models.EmailTypeConsentReminder,
		models.EmailTypeConsentDeadlineWarning,
		models.EmailTypeAccountSuspended,
	}

	service := &EmailTemplateService{}

	for _, emailType := range types {
		t.Run(emailType, func(t *testing.T) {
			subject, bodyHTML, _ := service.GetDefaultTemplateContent(emailType, "de")
			if subject == "" {
				t.Errorf("Email type %s has no default subject", emailType)
			}
			if bodyHTML == "" {
				t.Errorf("Email type %s has no default body HTML", emailType)
			}
		})
	}

	// Verify we have exactly 19 types
	if len(types) != 19 {
		t.Errorf("Expected 19 email types, got %d", len(types))
	}
}

// TestEmailTemplateService_ValidateTemplateContent tests template content validation
func TestEmailTemplateService_ValidateTemplateContent(t *testing.T) {
	tests := []struct {
		name      string
		subject   string
		bodyHTML  string
		wantError bool
	}{
		{
			name:      "valid content",
			subject:   "Test Subject",
			bodyHTML:  "<p>Test Body</p>",
			wantError: false,
		},
		{
			name:      "empty subject",
			subject:   "",
			bodyHTML:  "<p>Test Body</p>",
			wantError: true,
		},
		{
			name:      "empty body",
			subject:   "Test Subject",
			bodyHTML:  "",
			wantError: true,
		},
		{
			name:      "both empty",
			subject:   "",
			bodyHTML:  "",
			wantError: true,
		},
		{
			name:      "whitespace only subject",
			subject:   "   ",
			bodyHTML:  "<p>Test Body</p>",
			wantError: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			err := testValidateTemplateContent(tt.subject, tt.bodyHTML)
			if (err != nil) != tt.wantError {
				t.Errorf("validateTemplateContent() error = %v, wantError %v", err, tt.wantError)
			}
		})
	}
}

// testValidateTemplateContent is a test helper function to validate template content
func testValidateTemplateContent(subject, bodyHTML string) error {
	if strings.TrimSpace(subject) == "" {
		return &templateValidationError{Field: "subject", Message: "subject is required"}
	}
	if strings.TrimSpace(bodyHTML) == "" {
		return &templateValidationError{Field: "body_html", Message: "body_html is required"}
	}
	return nil
}

// templateValidationError represents a validation error in email templates
type templateValidationError struct {
	Field   string
	Message string
}

func (e *templateValidationError) Error() string {
	return e.Field + ": " + e.Message
}

// TestGetTestVariablesForType tests that test variables are properly generated for each email type
func TestGetTestVariablesForType(t *testing.T) {
	tests := []struct {
		emailType    string
		expectedVars []string
	}{
		// Auth Lifecycle
		{models.EmailTypeWelcome, []string{"user_name", "app_name"}},
		{models.EmailTypeEmailVerification, []string{"user_name", "verification_url"}},
		{models.EmailTypePasswordReset, []string{"reset_url"}},
		{models.EmailTypePasswordChanged, []string{"user_name", "changed_at"}},
		{models.EmailType2FAEnabled, []string{"user_name", "enabled_at"}},
		{models.EmailType2FADisabled, []string{"user_name", "disabled_at"}},
		{models.EmailTypeNewDeviceLogin, []string{"device", "location", "ip_address", "login_time"}},
		{models.EmailTypeSuspiciousActivity, []string{"activity_type", "activity_time"}},
		{models.EmailTypeAccountLocked, []string{"locked_at", "reason"}},
		{models.EmailTypeAccountUnlocked, []string{"unlocked_at"}},
		// GDPR/Privacy
		{models.EmailTypeDeletionRequested, []string{"deletion_date", "cancel_url"}},
		{models.EmailTypeDeletionConfirmed, []string{"deleted_at"}},
		{models.EmailTypeDataExportReady, []string{"download_url", "expires_in"}},
		{models.EmailTypeEmailChanged, []string{"old_email", "new_email"}},
		// Consent Management
		{models.EmailTypeNewVersionPublished, []string{"document_name", "version"}},
		{models.EmailTypeConsentReminder, []string{"document_name", "days_left"}},
		{models.EmailTypeConsentDeadlineWarning, []string{"document_name", "hours_left"}},
		{models.EmailTypeAccountSuspended, []string{"suspended_at", "reason"}},
	}

	for _, tt := range tests {
		t.Run(tt.emailType, func(t *testing.T) {
			vars := getTestVariablesForType(tt.emailType)
			for _, expected := range tt.expectedVars {
				if _, ok := vars[expected]; !ok {
					t.Errorf("getTestVariablesForType(%s) missing variable %s", tt.emailType, expected)
				}
			}
		})
	}
}

// getTestVariablesForType returns test variables for a given email type
func getTestVariablesForType(emailType string) map[string]string {
	// Common variables
	vars := map[string]string{
		"user_name":    "Max Mustermann",
		"user_email":   "max@example.com",
		"app_name":     "BreakPilot",
		"app_url":      "https://breakpilot.app",
		"support_url":  "https://breakpilot.app/support",
		"support_email": "support@breakpilot.app",
		"security_url": "https://breakpilot.app/security",
		"login_url":    "https://breakpilot.app/login",
	}

	switch emailType {
	case models.EmailTypeEmailVerification:
		vars["verification_url"] = "https://breakpilot.app/verify?token=xyz789"
		vars["verification_code"] = "ABC123"
		vars["expires_in"] = "24 Stunden"

	case models.EmailTypePasswordReset:
		vars["reset_url"] = "https://breakpilot.app/reset?token=abc123"
		vars["reset_code"] = "RST456"
		vars["expires_in"] = "1 Stunde"
		vars["ip_address"] = "192.168.1.1"

	case models.EmailTypePasswordChanged:
		vars["changed_at"] = "14.12.2025 15:30 Uhr"
		vars["ip_address"] = "192.168.1.1"
		vars["device_info"] = "Chrome auf MacOS"

	case models.EmailType2FAEnabled:
		vars["enabled_at"] = "14.12.2025 15:30 Uhr"
		vars["device_info"] = "Chrome auf MacOS"

	case models.EmailType2FADisabled:
		vars["disabled_at"] = "14.12.2025 15:30 Uhr"
		vars["ip_address"] = "192.168.1.1"

	case models.EmailTypeNewDeviceLogin:
		vars["device"] = "Chrome auf MacOS"
		vars["device_info"] = "Chrome auf MacOS"
		vars["location"] = "Berlin, Deutschland"
		vars["ip_address"] = "192.168.1.1"
		vars["login_time"] = "14.12.2025 15:30 Uhr"

	case models.EmailTypeSuspiciousActivity:
		vars["activity_type"] = "Mehrere fehlgeschlagene Logins"
		vars["activity_time"] = "14.12.2025 15:30 Uhr"
		vars["ip_address"] = "192.168.1.1"

	case models.EmailTypeAccountLocked:
		vars["locked_at"] = "14.12.2025 15:30 Uhr"
		vars["reason"] = "Zu viele fehlgeschlagene Login-Versuche"
		vars["unlock_time"] = "14.12.2025 16:30 Uhr"

	case models.EmailTypeAccountUnlocked:
		vars["unlocked_at"] = "14.12.2025 16:30 Uhr"

	case models.EmailTypeDeletionRequested:
		vars["requested_at"] = "14.12.2025 15:30 Uhr"
		vars["deletion_date"] = "14.01.2026"
		vars["cancel_url"] = "https://breakpilot.app/cancel-deletion?token=del123"
		vars["data_info"] = "Profildaten, Consent-Historie, Audit-Logs"

	case models.EmailTypeDeletionConfirmed:
		vars["deleted_at"] = "14.01.2026 00:00 Uhr"
		vars["feedback_url"] = "https://breakpilot.app/feedback"

	case models.EmailTypeDataExportReady:
		vars["download_url"] = "https://breakpilot.app/download/export123"
		vars["expires_in"] = "7 Tage"
		vars["file_size"] = "2.5 MB"

	case models.EmailTypeEmailChanged:
		vars["old_email"] = "old@example.com"
		vars["new_email"] = "new@example.com"
		vars["changed_at"] = "14.12.2025 15:30 Uhr"

	case models.EmailTypeEmailChangeVerify:
		vars["new_email"] = "new@example.com"
		vars["verification_url"] = "https://breakpilot.app/verify-email?token=ver123"
		vars["expires_in"] = "24 Stunden"

	case models.EmailTypeNewVersionPublished:
		vars["document_name"] = "Datenschutzerklärung"
		vars["document_type"] = "privacy"
		vars["version"] = "2.0.0"
		vars["consent_url"] = "https://breakpilot.app/consent"
		vars["deadline"] = "31.12.2025"

	case models.EmailTypeConsentReminder:
		vars["document_name"] = "Nutzungsbedingungen"
		vars["days_left"] = "7"
		vars["consent_url"] = "https://breakpilot.app/consent"
		vars["deadline"] = "21.12.2025"

	case models.EmailTypeConsentDeadlineWarning:
		vars["document_name"] = "Nutzungsbedingungen"
		vars["hours_left"] = "24 Stunden"
		vars["consent_url"] = "https://breakpilot.app/consent"
		vars["consequences"] = "Ihr Konto wird temporär suspendiert."

	case models.EmailTypeAccountSuspended:
		vars["suspended_at"] = "14.12.2025 15:30 Uhr"
		vars["reason"] = "Fehlende Zustimmung zu Pflichtdokumenten"
		vars["documents"] = "- Nutzungsbedingungen v2.0\n- Datenschutzerklärung v3.0"
		vars["consent_url"] = "https://breakpilot.app/consent"
	}

	return vars
}

// TestEmailTemplateService_HTMLEscape tests that HTML is properly escaped in text version
func TestEmailTemplateService_HTMLEscape(t *testing.T) {
	tests := []struct {
		name     string
		html     string
		expected string
	}{
		{
			name:     "simple paragraph",
			html:     "<p>Hello World</p>",
			expected: "Hello World",
		},
		{
			name:     "link",
			html:     `<a href="https://example.com">Click here</a>`,
			expected: "Click here",
		},
		{
			name:     "bold text",
			html:     "<strong>Important</strong>",
			expected: "Important",
		},
		{
			name:     "nested tags",
			html:     "<div><p><strong>Nested</strong> text</p></div>",
			expected: "Nested text",
		},
		{
			name:     "multiple tags",
			html:     "<h1>Title</h1><p>Paragraph</p>",
			expected: "TitleParagraph",
		},
		{
			name:     "self-closing tag",
			html:     "Line1<br/>Line2",
			expected: "Line1Line2",
		},
	}

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

// stripHTMLTags removes HTML tags from a string
func stripHTMLTags(html string) string {
	result := ""
	inTag := false
	for _, r := range html {
		if r == '<' {
			inTag = true
			continue
		}
		if r == '>' {
			inTag = false
			continue
		}
		if !inTag {
			result += string(r)
		}
	}
	return result
}

// TestEmailTemplateService_AllTemplatesHaveVariables tests that all templates define their required variables
func TestEmailTemplateService_AllTemplatesHaveVariables(t *testing.T) {
	service := &EmailTemplateService{}
	templateTypes := service.GetAllTemplateTypes()

	for _, tt := range templateTypes {
		t.Run(tt.TemplateType, func(t *testing.T) {
			// Get default template content
			subject, bodyHTML, bodyText := service.GetDefaultTemplateContent(tt.TemplateType, "de")

			// Check that variables defined in template type are present in the content
			for _, varName := range tt.Variables {
				placeholder := "{{" + varName + "}}"
				foundInSubject := strings.Contains(subject, placeholder)
				foundInHTML := strings.Contains(bodyHTML, placeholder)
				foundInText := strings.Contains(bodyText, placeholder)

				// Variable should be present in at least one of subject, HTML or text
				if !foundInSubject && !foundInHTML && !foundInText {
					// Note: This is a warning, not an error, as some variables might be optional
					t.Logf("Warning: Variable %s defined for %s but not found in template content", varName, tt.TemplateType)
				}
			}

			// Check that all variables in content are defined
			re := regexp.MustCompile(`\{\{(\w+)\}\}`)
			allMatches := re.FindAllStringSubmatch(subject+bodyHTML+bodyText, -1)
			definedVars := make(map[string]bool)
			for _, v := range tt.Variables {
				definedVars[v] = true
			}

			for _, match := range allMatches {
				if len(match) > 1 {
					varName := match[1]
					if !definedVars[varName] {
						t.Logf("Warning: Variable {{%s}} found in template but not defined in variables list for %s", varName, tt.TemplateType)
					}
				}
			}
		})
	}
}

// TestEmailTemplateService_TemplateVariableDescriptions tests that all variables have descriptions
func TestEmailTemplateService_TemplateVariableDescriptions(t *testing.T) {
	service := &EmailTemplateService{}
	templateTypes := service.GetAllTemplateTypes()

	for _, tt := range templateTypes {
		t.Run(tt.TemplateType, func(t *testing.T) {
			for _, varName := range tt.Variables {
				if desc, ok := tt.Descriptions[varName]; !ok || desc == "" {
					t.Errorf("Variable %s in %s has no description", varName, tt.TemplateType)
				}
			}
		})
	}
}

// TestEmailTemplateService_GermanTemplatesAreComplete tests that all German templates are fully translated
func TestEmailTemplateService_GermanTemplatesAreComplete(t *testing.T) {
	service := &EmailTemplateService{}

	emailTypes := []string{
		models.EmailTypeWelcome,
		models.EmailTypeEmailVerification,
		models.EmailTypePasswordReset,
		models.EmailTypePasswordChanged,
		models.EmailType2FAEnabled,
		models.EmailType2FADisabled,
		models.EmailTypeNewDeviceLogin,
		models.EmailTypeSuspiciousActivity,
		models.EmailTypeAccountLocked,
		models.EmailTypeAccountUnlocked,
		models.EmailTypeDeletionRequested,
		models.EmailTypeDeletionConfirmed,
		models.EmailTypeDataExportReady,
		models.EmailTypeEmailChanged,
		models.EmailTypeNewVersionPublished,
		models.EmailTypeConsentReminder,
		models.EmailTypeConsentDeadlineWarning,
		models.EmailTypeAccountSuspended,
	}

	germanKeywords := []string{"Hallo", "freundlichen", "Grüßen", "BreakPilot", "Ihr"}

	for _, emailType := range emailTypes {
		t.Run(emailType, func(t *testing.T) {
			subject, bodyHTML, bodyText := service.GetDefaultTemplateContent(emailType, "de")

			// Check that German text is present
			foundGerman := false
			for _, keyword := range germanKeywords {
				if strings.Contains(bodyHTML, keyword) || strings.Contains(bodyText, keyword) {
					foundGerman = true
					break
				}
			}

			if !foundGerman {
				t.Errorf("Template %s does not appear to be in German", emailType)
			}

			// Check that subject is not just the fallback
			if subject == "No template" {
				t.Errorf("Template %s has fallback subject instead of German subject", emailType)
			}
		})
	}
}

// TestEmailTemplateService_HTMLStructure tests that HTML templates have valid structure
func TestEmailTemplateService_HTMLStructure(t *testing.T) {
	service := &EmailTemplateService{}

	emailTypes := []string{
		models.EmailTypeWelcome,
		models.EmailTypeEmailVerification,
		models.EmailTypePasswordReset,
	}

	for _, emailType := range emailTypes {
		t.Run(emailType, func(t *testing.T) {
			_, bodyHTML, _ := service.GetDefaultTemplateContent(emailType, "de")

			// Check for basic HTML structure
			if !strings.Contains(bodyHTML, "<!DOCTYPE html>") {
				t.Errorf("Template %s missing DOCTYPE", emailType)
			}
			if !strings.Contains(bodyHTML, "<html>") {
				t.Errorf("Template %s missing <html> tag", emailType)
			}
			if !strings.Contains(bodyHTML, "</html>") {
				t.Errorf("Template %s missing closing </html> tag", emailType)
			}
			if !strings.Contains(bodyHTML, "<body") {
				t.Errorf("Template %s missing <body> tag", emailType)
			}
			if !strings.Contains(bodyHTML, "</body>") {
				t.Errorf("Template %s missing closing </body> tag", emailType)
			}
		})
	}
}

// BenchmarkReplaceVariables benchmarks variable replacement
func BenchmarkReplaceVariables(b *testing.B) {
	template := "Hallo {{user_name}}, Ihr Link: {{reset_url}}, gültig bis {{expires_in}}"
	variables := map[string]string{
		"user_name":  "Max Mustermann",
		"reset_url":  "https://example.com/reset?token=abc123",
		"expires_in": "24 Stunden",
	}

	for i := 0; i < b.N; i++ {
		replaceVariables(template, variables)
	}
}

// BenchmarkStripHTMLTags benchmarks HTML tag stripping
func BenchmarkStripHTMLTags(b *testing.B) {
	html := "<html><body><h1>Title</h1><p>This is a <strong>test</strong> paragraph with <a href='#'>links</a>.</p></body></html>"

	for i := 0; i < b.N; i++ {
		stripHTMLTags(html)
	}
}
