using Core.Entities;
namespace Core.Models;
///
/// Result of parsing a student event ranking CSV.
///
public class StudentEventRankingParseResult
{
///
/// Accepted ranking matches, including the raw CSV text and fuzzy scores.
///
public List Matches { get; set; } = [];
///
/// Unmatched students, unmatched or ambiguous events, and other row-level issues.
///
public List Issues { get; set; } = [];
///
/// Critical errors that prevented parsing (for example a missing header).
///
public List Errors { get; set; } = [];
///
/// Non-critical warnings about the file as a whole.
///
public List Warnings { get; set; } = [];
///
/// Accepted rankings without match metadata.
///
public IReadOnlyList Rankings => [.. Matches.Select(m => m.Ranking)];
///
/// Number of accepted ranking rows.
///
public int TotalParsed => Matches.Count;
///
/// Distinct students who have at least one accepted rank.
/// Uses Id when assigned, otherwise first and last name, so unsaved parsed students stay distinct.
///
public IReadOnlyList StudentsWithAcceptedRanks =>
[.. Matches
.Select(m => m.Ranking.Student)
.GroupBy(s => s.Id != 0 ? $"id:{s.Id}" : $"name:{s.FirstName}|{s.LastName}")
.Select(g => g.First())];
///
/// True when no critical parse errors were recorded.
///
public bool IsSuccess => Errors.Count == 0;
}
///
/// A successfully matched ranking cell from the CSV.
///
public class StudentEventRankingMatch
{
public required StudentEventRanking Ranking { get; set; }
public string RawStudentName { get; set; } = string.Empty;
public string RawEventName { get; set; } = string.Empty;
public int StudentScore { get; set; }
public int EventScore { get; set; }
public int RowNumber { get; set; }
}
///
/// A row-level problem encountered while parsing rankings.
///
public class StudentEventRankingIssue
{
public int RowNumber { get; set; }
public int Rank { get; set; }
public string RawStudentName { get; set; } = string.Empty;
public string RawEventName { get; set; } = string.Empty;
public StudentEventRankingIssueType IssueType { get; set; }
public string Message { get; set; } = string.Empty;
public string? SuggestedEventName { get; set; }
public int? Score { get; set; }
}
///
/// Types of issues reported while parsing student event rankings.
///
public enum StudentEventRankingIssueType
{
UnmatchedStudent,
UnmatchedEvent,
AmbiguousEvent,
DuplicateEvent,
DuplicateRank,
InvalidFormat
}