package basic

import "testing"

func TestNormalizeName(t *testing.T) {
	tests := []struct {
		input    string
		expected string
	}{
		// Basic capitalization
		{"JOHN", "John"},
		{"doe", "Doe"},
		{"jOhN", "jOhN"}, // mixed case — trust user input

		// O' prefix
		{"O'BRIAN", "O'Brian"},
		{"o'connor", "O'Connor"},
		{"O'NEIL", "O'Neil"},

		// Mc prefix
		{"MCDONALD", "McDonald"},
		{"mcdonald", "McDonald"},
		{"MCBRIDE", "McBride"},

		// Mac prefix (len >= 5 to avoid false positives)
		{"MACARTHUR", "MacArthur"},
		{"macarthur", "MacArthur"},
		{"MACDONALD", "MacDonald"},

		// Mac prefix - short words should NOT get Mac treatment
		{"MACK", "Mack"},
		{"macy", "Macy"},
		{"mace", "Mace"},
		{"mach", "Mach"},

		// Hyphenated names
		{"SMITH-JONES", "Smith-Jones"},
		{"smith-jones", "Smith-Jones"},
		{"O'BRIEN-MCDONALD", "O'Brien-McDonald"},

		// Roman numerals and suffixes
		{"iii", "III"},
		{"III", "III"},
		{"iv", "IV"},
		{"jr", "Jr."},
		{"sr", "Sr."},
		{"ii", "II"},

		// Compound surnames (De, Di, La, Le, Lo, Du)
		{"DESANTIS", "DeSantis"},
		{"devries", "DeVries"},
		{"DEMARCO", "DeMarco"},
		{"DIMAGGIO", "DiMaggio"},
		{"dicaprio", "DiCaprio"},
		{"LASALLE", "LaSalle"},
		{"lafleur", "LaFleur"},
		{"LEBLANC", "LeBlanc"},
		{"lebron", "LeBron"},
		{"LOPRESTI", "LoPresti"},
		{"DUBOIS", "DuBois"},
		{"dupont", "DuPont"},

		// Compound surname prefixes should NOT affect regular names
		{"DEAN", "Dean"},
		{"DENNIS", "Dennis"},
		{"DIANA", "Diana"},
		{"LAURA", "Laura"},
		{"LEON", "Leon"},

		// Multi-word last names
		{"DE LA CRUZ", "De La Cruz"},
		{"VAN DER BERG", "Van Der Berg"},

		// Whitespace handling
		{"  JOHN  ", "John"},
		{"", ""},
		{"   ", ""},

		// Mixed case — skip normalization, trust user input
		{"John", "John"},
		{"Smith", "Smith"},
		{"DeSantis", "DeSantis"},
		{"DiCaprio", "DiCaprio"},
		{"O'Brien", "O'Brien"},
		{"LeBron", "LeBron"},
		{"MacArthur", "MacArthur"},
		{"McDonald", "McDonald"},
	}

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

func TestNameContainsProfanity(t *testing.T) {
	tests := []struct {
		input    string
		expected bool
	}{
		// Should flag
		{"fuck", true},
		{"FUCK", true},
		{"Shit", true},
		{"ass", true},

		// Should NOT flag — profane substrings inside real names
		{"Massimo", false},
		{"Dickens", false},
		{"Cockburn", false},
		{"Draper", false},
		{"Ashton", false},
		{"Cassidy", false},

		// Normal names
		{"John", false},
		{"Smith", false},
		{"O'Brien", false},

		// Profanity in hyphenated or multi-word name
		{"Fuck-Face", true},
		{"Dick Head", true},

		// Leet speak
		{"b1tch", true},
		{"a$$", true},
		{"sh!t", true},
		{"fvck", false}, // not in leet map, won't match
		{"f4g", true},
		{"4ss", true},
		{"d1ck", true},
		{"pu$$y", true},

		// Empty
		{"", false},
	}

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