using Core.Entities;
using FuzzySharp;
namespace Core.Utility;
///
/// Utility class for matching team names from clipboard text using fuzzy matching.
///
public static class TeamClipboardMatcher
{
///
/// Matches team names from clipboard text against available teams using fuzzy matching.
///
/// The text content from the clipboard.
/// The collection of available teams to match against.
/// The minimum fuzzy match score threshold (0-100). Default is 85.
/// A list of teams that match the clipboard text, ordered by match quality.
public static List MatchTeamsFromClipboard(
string clipboardText,
IEnumerable availableTeams,
int matchThreshold = 85)
{
var matchedTeams = new List();
var teamsList = availableTeams.ToList();
if (string.IsNullOrWhiteSpace(clipboardText) || !teamsList.Any())
{
return matchedTeams;
}
// Split clipboard text by newlines
var lines = clipboardText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
// Extract team name portion (before " - " if present, as clipboard format includes student lists)
var teamName = ExtractTeamNameFromLine(line);
// Skip empty lines or lines that look like headers/metadata
if (ShouldSkipLine(teamName))
{
continue;
}
// Find best match using fuzzy matching
var matchedTeam = FindBestMatch(teamName, teamsList, matchThreshold);
if (matchedTeam != null && !matchedTeams.Any(t => t.Id == matchedTeam.Id))
{
matchedTeams.Add(matchedTeam);
}
}
return matchedTeams;
}
private static string ExtractTeamNameFromLine(string line)
{
var dashIndex = line.IndexOf(" - ");
if (dashIndex > 0)
{
return line.Substring(0, dashIndex).Trim();
}
return line.Trim();
}
private static bool ShouldSkipLine(string teamName)
{
return string.IsNullOrWhiteSpace(teamName) ||
teamName.StartsWith("--") ||
teamName.Equals("Unscheduled", StringComparison.OrdinalIgnoreCase);
}
private static Team? FindBestMatch(string teamName, List availableTeams, int matchThreshold)
{
// Normalize both strings to lowercase for case-insensitive comparison
var normalizedTeamName = teamName.ToLowerInvariant();
var bestMatch = availableTeams
.Select(team => new
{
Team = team,
Score = Fuzz.Ratio(normalizedTeamName, team.ToString().ToLowerInvariant())
})
.Where(x => x.Score >= matchThreshold)
.OrderByDescending(x => x.Score)
.FirstOrDefault();
return bestMatch?.Team;
}
}