using GmRelay.Shared.Domain;
using GmRelay.Shared.Rendering;
using NetCord;
using NetCord.Rest;

namespace GmRelay.DiscordBot.Rendering;

public static class DiscordSessionBatchRenderer
{
    public static (IReadOnlyList<EmbedProperties> Embeds, IReadOnlyList<ActionRowProperties> ActionRows) Render(SessionBatchViewModel view)
    {
        var embeds = new List<EmbedProperties>();
        var actionRows = new List<ActionRowProperties>();

        foreach (var session in view.Sessions)
        {
            var embed = BuildEmbed(view.Title, session);
            embeds.Add(embed);

            if (session.AvailableActions.Count > 0)
            {
                var actionRow = new ActionRowProperties();
                foreach (var action in session.AvailableActions)
                {
                    actionRow.Add(new ButtonProperties(
                        $"{action.ActionKey}:{action.SessionId}",
                        action.Label,
                        ButtonStyle.Primary));
                }
                actionRows.Add(actionRow);
            }
        }

        return (embeds, actionRows);
    }

    private static EmbedProperties BuildEmbed(string title, SessionViewItem session)
    {
        var embed = new EmbedProperties()
            .WithTitle($"{title} — {session.ScheduledAt.FormatMoscow()}");

        if (SessionStatus.IsCancelled(session.Status))
        {
            embed = embed.WithDescription("❌ Сессия отменена");
        }
        else
        {
            embed = embed.WithDescription(BuildPlayerDescription(session));
        }

        var fields = new List<EmbedFieldProperties>
        {
            new EmbedFieldProperties()
                .WithName("👥 Заполненность")
                .WithValue(session.MaxPlayers.HasValue
                    ? $"{session.ActivePlayerCount}/{session.MaxPlayers.Value}"
                    : $"{session.ActivePlayerCount}")
                .WithInline(),

            new EmbedFieldProperties()
                .WithName("⏳ Лист ожидания")
                .WithValue(session.WaitlistedPlayers.Count > 0
                    ? session.WaitlistedPlayers.Count.ToString()
                    : "—")
                .WithInline(),

            new EmbedFieldProperties()
                .WithName("📊 Статус")
                .WithValue(FormatStatus(session.Status))
                .WithInline()
        };

        var embedUrl = DiscordEmbedUrls.NormalizeHttpUrl(session.JoinLink);
        if (embedUrl is not null)
        {
            embed = embed.WithUrl(embedUrl);
        }

        embed = embed.WithColor(GetColor(session));
        embed = embed.AddFields(fields);

        return embed;
    }

    private static string BuildPlayerDescription(SessionViewItem session)
    {
        if (session.ActivePlayers.Count == 0)
            return "👥 Пока никто не записался";

        var lines = session.ActivePlayers
            .Select(p => $"• {p.DisplayName}")
            .ToList();

        if (session.WaitlistedPlayers.Count > 0)
        {
            lines.Add("");
            lines.Add($"⏳ Лист ожидания ({session.WaitlistedPlayers.Count}):");
            lines.AddRange(session.WaitlistedPlayers.Select(p => $"• {p.DisplayName}"));
        }

        return string.Join('\n', lines);
    }

    private static string FormatStatus(string status) => status switch
    {
        SessionStatus.Planned => "Запланирована",
        SessionStatus.ConfirmationSent => "Ожидает подтверждения",
        SessionStatus.Confirmed => "Подтверждена",
        SessionStatus.Cancelled => "Отменена",
        _ => status
    };

    private static Color GetColor(SessionViewItem session)
    {
        if (SessionStatus.IsCancelled(session.Status))
            return new Color(0xED4245);

        if (session.Status == SessionStatus.Confirmed)
            return new Color(0x5865F2);

        if (session.MaxPlayers.HasValue && session.ActivePlayerCount >= session.MaxPlayers.Value)
            return new Color(0xFEE75C);

        return new Color(0x57F287);
    }
}
