namespace GmRelay.DiscordBot.Rendering; using GmRelay.Shared.Domain; using GmRelay.Shared.Features.Sessions.RescheduleSession; using NetCord; using NetCord.Rest; public static class DiscordRescheduleVotingRenderer { public static (EmbedProperties Embed, ActionRowProperties ActionRow) Render( string title, DateTime currentTime, DateTimeOffset deadline, IReadOnlyList options, IReadOnlyList participants, IReadOnlyList votes) { var votesByOption = votes.GroupBy(v => v.OptionId).ToDictionary(g => g.Key, g => g.ToList()); var votedPlayerIds = votes.Select(v => v.PlayerId).ToHashSet(); var pending = participants.Where(p => !votedPlayerIds.Contains(p.PlayerId)).Select(p => p.DisplayName).ToList(); var sb = new System.Text.StringBuilder(); sb.AppendLine($"📅 Текущее время: {currentTime.FormatMoscow()} (МСК)"); sb.AppendLine($"⏳ Дедлайн: {deadline.FormatMoscow()} (МСК)"); sb.AppendLine(); sb.AppendLine("Выберите один из вариантов:"); foreach (var option in options.OrderBy(o => o.DisplayOrder)) { var optionVotes = votesByOption.GetValueOrDefault(option.OptionId, []); sb.AppendLine($"{option.DisplayOrder}. **{option.ProposedAt.FormatMoscow()}** (МСК) — {optionVotes.Count} голосов"); if (optionVotes.Count > 0) { sb.AppendLine($" {string.Join(", ", optionVotes.Select(v => v.DisplayName))}"); } } if (pending.Count > 0) { sb.AppendLine(); sb.AppendLine($"Не проголосовали: {string.Join(", ", pending)}"); } sb.AppendLine(); sb.AppendLine($"Голосов: {votedPlayerIds.Count}/{participants.Count}"); sb.AppendLine("Правило: побеждает вариант с большинством голосов к дедлайну; при ничьей перенос не применяется."); var embed = new EmbedProperties() .WithTitle($"🔄 Перенос сессии «{title}»") .WithDescription(sb.ToString()) .WithColor(new Color(0xFEE75C)); var actionRow = new ActionRowProperties(); foreach (var option in options.OrderBy(o => o.DisplayOrder)) { actionRow.Add(new ButtonProperties( $"reschedule_vote:{option.OptionId}", $"{option.DisplayOrder}. {FormatButtonTime(option.ProposedAt)}", ButtonStyle.Primary)); } return (embed, actionRow); } private static string FormatButtonTime(DateTimeOffset utc) => utc.ToOffset(TimeSpan.FromHours(3)).ToString("dd.MM HH:mm", System.Globalization.CultureInfo.InvariantCulture); }