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<RescheduleOptionDto> options,
        IReadOnlyList<VoteParticipantDto> participants,
        IReadOnlyList<RescheduleOptionVoteDto> 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);
}
