using System.Text;
using Core.Entities;
using Core.Models;
namespace GoogleSheetsScheduleImport;
///
/// Emits PDF-style section headers Event Name - MS / Event Name - HS before occurrence lines,
/// matching competition schedule imports.
///
public static class GroupedImportTextEmitter
{
private readonly struct SectionKey(int eventDefinitionId, SchoolLevel level) : IEquatable
{
public int EventDefinitionId { get; } = eventDefinitionId;
public SchoolLevel Level { get; } = level;
public bool Equals(SectionKey other) =>
EventDefinitionId == other.EventDefinitionId && Level == other.Level;
public override bool Equals(object? obj) => obj is SectionKey other && Equals(other);
public override int GetHashCode() => HashCode.Combine(EventDefinitionId, Level);
}
public static string Build(
IReadOnlyList<(string SheetTitle, string SectionHeader, List Lines)> sheets,
IReadOnlyList matchableEvents,
int year)
{
var idToDef = matchableEvents.Where(e => e.Id != 0).ToDictionary(e => e.Id);
var sb = new StringBuilder();
foreach (var (sheetTitle, _, lines) in sheets)
{
sb.AppendLine($"# {sheetTitle}");
var general = new List();
var bySection = new Dictionary>();
foreach (var line in lines)
{
if (!OccurrenceEventMatcher.TryMatch(line.Name, matchableEvents, out var evt, out var lvl)
|| evt == null
|| !lvl.HasValue)
{
general.Add(line);
continue;
}
var key = new SectionKey(evt.Id, lvl.Value);
if (!bySection.TryGetValue(key, out var list))
{
list = [];
bySection[key] = list;
}
list.Add(line);
}
foreach (var key in bySection.Keys.OrderBy(k => HeaderSortKey(idToDef, k), StringComparer.OrdinalIgnoreCase))
{
if (!idToDef.TryGetValue(key.EventDefinitionId, out var def))
continue;
sb.AppendLine($"{def.Name} - {SchoolLevelPrefixParser.ToSectionSuffix(key.Level)}");
foreach (var line in OccurrenceChronologicalSort.Sort(bySection[key], year))
{
var displayName = OccurrenceDisplayNameReducer.ReduceForSection(line.Name, def, key.Level);
sb.AppendLine(ImportLineFormatter.FormatOccurrenceLine(line with { Name = displayName }));
}
}
if (general.Count > 0)
{
sb.AppendLine("General Schedule");
foreach (var line in OccurrenceChronologicalSort.Sort(general, year))
sb.AppendLine(ImportLineFormatter.FormatOccurrenceLine(line));
}
sb.AppendLine();
}
return sb.ToString().TrimEnd();
}
private static string HeaderSortKey(Dictionary idToDef, SectionKey key)
{
if (!idToDef.TryGetValue(key.EventDefinitionId, out var def))
return $"{key.EventDefinitionId} - {key.Level}";
return $"{def.Name} - {SchoolLevelPrefixParser.ToSectionSuffix(key.Level)}";
}
}