namespace GoogleSheetsScheduleImport;
///
/// Collapses duplicate site-wide rows (same event name, date, time) that appear in every location column
/// (e.g. CURFEW shaded across all rooms) into a single line with no location — still under
/// General Schedule, which the parser maps to .
///
public static class GlobalEventDeduplicator
{
private static readonly HashSet BuiltinSiteWideNames = new(StringComparer.OrdinalIgnoreCase)
{
"CURFEW"
};
///
/// First occurrence in row/column order is kept; location is cleared so the import line is not room-specific.
///
public static List Deduplicate(
IReadOnlyList lines,
IReadOnlyCollection? extraSiteWideNames = null)
{
var siteWide = new HashSet(BuiltinSiteWideNames, StringComparer.OrdinalIgnoreCase);
if (extraSiteWideNames != null)
{
foreach (var n in extraSiteWideNames)
{
if (!string.IsNullOrWhiteSpace(n))
siteWide.Add(n.Trim());
}
}
var seen = new HashSet<(string Name, string Month, int Day, string Time)>();
var ordered = lines.OrderBy(l => l.SourceRowStart).ThenBy(l => l.SourceCol).ToList();
var result = new List(ordered.Count);
foreach (var line in ordered)
{
var name = TextNormalization.ForEmitLine(line.Name);
if (string.IsNullOrEmpty(name) || !siteWide.Contains(name))
{
result.Add(line);
continue;
}
var key = (name, line.Month, line.Day, line.TimeRange);
if (!seen.Add(key))
continue;
result.Add(line with { Location = string.Empty, Name = name });
}
return result;
}
}