package utils

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestValidateSlug_ReservedKeywords(t *testing.T) {
	tests := []struct {
		slug  string
		valid bool
	}{
		{"my-tenant", true},
		{"admin", false},
		{"api", false},
		{"static", false},
		{"security", false},
		{"billing", false},
		{"ns", false},
		{"mx", false},
		{"webmaster", false},
		{"status", false},
	}

	for _, tt := range tests {
		t.Run(tt.slug, func(t *testing.T) {
			valid, msg := ValidateSlug(tt.slug)
			assert.Equal(t, tt.valid, valid, "Slug: "+tt.slug+" - "+msg)
		})
	}
}

func TestValidateSlug_Format(t *testing.T) {
	tests := []struct {
		slug  string
		valid bool
	}{
		{"abc", true},
		{"a-b-c", true},
		{"123", true},
		{"ab", false},           // Too short
		{"-abc", false},         // Starts with hyphen
		{"abc-", false},         // Ends with hyphen
		{"Abc", true},           // Case insensitive check (converted to lower)
		{"invalid_slug", false}, // Contains underscore
		{"too-long-slug-name-that-exceeds-thirty-two-chars", false},
	}

	for _, tt := range tests {
		t.Run(tt.slug, func(t *testing.T) {
			valid, _ := ValidateSlug(tt.slug)
			assert.Equal(t, tt.valid, valid)
		})
	}
}

func TestGenerateSlug(t *testing.T) {
	tests := []struct {
		name     string
		expected string
	}{
		{"Hello World", "hello-world"},
		{"My Company!@#", "my-company"},
		{"---Test---", "test"},
		{"   Spaces   ", "spaces"},
		{"A VERY LONG NAME THAT EXCEEDS THIRTY TWO CHARACTERS", "a-very-long-name-that-exc"},
		{"한글 테스트", "tenant"}, // Non-ascii characters will be replaced by hyphens and trimmed to empty, then fallback to "tenant"
		{"Test 한글 Mix", "test-mix"},
		{"", "tenant"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			slug := GenerateSlug(tt.name)
			assert.Equal(t, tt.expected, slug)
			// Ensure generated slug is valid (unless it's reserved like "slug" wasn't reserved, but let's check format)
			if !reservedSlugs[slug] {
				valid, _ := ValidateSlug(slug)
				assert.True(t, valid, "Generated slug should be valid format")
			}
		})
	}
}

func TestGenerateUniqueSlug(t *testing.T) {
	existingSlugs := map[string]bool{
		"my-company":   true,
		"my-company-1": true,
		"test":         true,
	}

	existsFunc := func(slug string) bool {
		return existingSlugs[slug]
	}

	tests := []struct {
		name     string
		expected string
	}{
		{"My Company", "my-company-2"},
		{"Test", "test-1"},
		{"New Company", "new-company"},
		{"admin", "admin-1"}, // "admin" is reserved, so it should append suffix
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			slug := GenerateUniqueSlug(tt.name, existsFunc)
			assert.Equal(t, tt.expected, slug)
			valid, _ := ValidateSlug(slug)
			assert.True(t, valid, "Generated unique slug should be valid")
		})
	}
}
