package utils

import (
	"testing"
)

func TestSanitizeString(t *testing.T) {
	s := DefaultSanitizer()

	tests := []struct {
		name     string
		input    string
		expected string
	}{
		{"simple text", "hello world", "hello world"},
		{"with whitespace", "  hello  ", "hello"},
		{"with html", "<script>alert('xss')</script>", "&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;"},
		{"empty string", "", ""},
		{"special chars", "café & thé", "café &amp; thé"},
	}

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

func TestSanitizeSlug(t *testing.T) {
	s := DefaultSanitizer()

	tests := []struct {
		name     string
		input    string
		expected string
	}{
		{"simple text", "Hello World", "hello-world"},
		{"special chars", "Café & Thé!", "caf-th"},
		{"multiple spaces", "hello   world", "hello-world"},
		{"already slug", "hello-world", "hello-world"},
		{"numbers", "test 123", "test-123"},
	}

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

func TestSanitizeName(t *testing.T) {
	s := DefaultSanitizer()
	s.MaxNameLength = 10

	tests := []struct {
		name     string
		input    string
		expected string
	}{
		{"short name", "John", "John"},
		{"max length", "1234567890", "1234567890"},
		{"over limit", "12345678901", "1234567890"},
	}

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

func TestStripHTML(t *testing.T) {
	tests := []struct {
		name     string
		input    string
		expected string
	}{
		{"simple html", "<p>hello</p>", "hello"},
		{"script tag", "<script>alert('xss')</script>", "alert('xss')"},
		{"nested tags", "<div><span>text</span></div>", "text"},
		{"no html", "plain text", "plain text"},
	}

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

func TestSanitizeEmail(t *testing.T) {
	s := DefaultSanitizer()

	tests := []struct {
		name     string
		input    string
		expected string
	}{
		{"simple email", "Test@Example.COM", "test@example.com"},
		{"with whitespace", "  test@example.com  ", "test@example.com"},
		{"empty string", "", ""},
	}

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

	// Test max length
	t.Run("over max length", func(t *testing.T) {
		s.MaxEmailLength = 10
		longEmail := "abcdefghijklmnop@example.com"
		result := s.SanitizeEmail(longEmail)
		if result != "" {
			t.Errorf("SanitizeEmail with over max length should return empty, got %q", result)
		}
	})
}

func TestSanitizeDescription(t *testing.T) {
	s := DefaultSanitizer()
	s.MaxDescriptionLength = 50 // Larger limit for testing

	tests := []struct {
		name     string
		input    string
		expected string
	}{
		{"short description", "Hello world", "Hello world"},
		{"with html", "<b>Bold</b> text", "&lt;b&gt;Bold&lt;/b&gt; text"},
		{"empty string", "", ""},
	}

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

	// Test truncation separately
	t.Run("over limit", func(t *testing.T) {
		s.MaxDescriptionLength = 10
		result := s.SanitizeDescription("This is a very long text")
		if len([]rune(result)) > 10 {
			t.Errorf("SanitizeDescription should truncate to MaxDescriptionLength")
		}
	})
}

func TestDefaultSanitizer(t *testing.T) {
	s := DefaultSanitizer()
	if s == nil {
		t.Error("DefaultSanitizer should not return nil")
	}
	if s.MaxNameLength != 255 {
		t.Errorf("MaxNameLength = %d, want 255", s.MaxNameLength)
	}
	if s.MaxDescriptionLength != 10000 {
		t.Errorf("MaxDescriptionLength = %d, want 10000", s.MaxDescriptionLength)
	}
	if s.MaxEmailLength != 320 {
		t.Errorf("MaxEmailLength = %d, want 320", s.MaxEmailLength)
	}
}
