using GmRelay.Shared.Domain;
using Telegram.Bot.Types.ReplyMarkups;

namespace GmRelay.Shared.Rendering;

public sealed record SessionBatchDto(Guid SessionId, DateTime ScheduledAt, string Status, int? MaxPlayers);
public sealed record ParticipantBatchDto(Guid SessionId, string DisplayName, string? TelegramUsername, string RegistrationStatus);

public static class SessionBatchRenderer
{
    public static (string Text, InlineKeyboardMarkup Markup) Render(
        string title,
        IReadOnlyList<SessionBatchDto> sessions,
        IReadOnlyList<ParticipantBatchDto> participants)
    {
        var activeSessions = sessions.OrderBy(s => s.ScheduledAt).ToList();
        
        var messageText = $"🎲 <b>Новые игры:</b> {System.Net.WebUtility.HtmlEncode(title)}\n\n" +
                          $"<b>Расписание:</b>\n\n";

        var buttons = new List<InlineKeyboardButton[]>();

        foreach (var session in activeSessions)
        {
            var sessionPlayers = participants
                .Where(p => p.SessionId == session.SessionId && p.RegistrationStatus == ParticipantRegistrationStatus.Active)
                .ToList();
            var waitlistedPlayers = participants
                .Where(p => p.SessionId == session.SessionId && p.RegistrationStatus == ParticipantRegistrationStatus.Waitlisted)
                .ToList();
            
            messageText += $"📅 <b>{session.ScheduledAt.FormatMoscow()}</b>\n";
            messageText += session.MaxPlayers.HasValue
                ? $"👥 Места: {sessionPlayers.Count}/{session.MaxPlayers.Value}\n"
                : $"👥 Игроки ({sessionPlayers.Count}):\n";
            
            if (sessionPlayers.Count > 0)
            {
                messageText += string.Join("\n", sessionPlayers.Select(p => $"  👤 {(p.TelegramUsername != null ? "@" + p.TelegramUsername : p.DisplayName)}")) + "\n";
            }
            else
            {
                messageText += "  <i>Пока никто не записался</i>\n";
            }

            if (waitlistedPlayers.Count > 0)
            {
                messageText += $"⏳ Лист ожидания ({waitlistedPlayers.Count}):\n";
                messageText += string.Join("\n", waitlistedPlayers.Select(p => $"  ⏱ {(p.TelegramUsername != null ? "@" + p.TelegramUsername : p.DisplayName)}")) + "\n";
            }

            if (SessionStatus.IsCancelled(session.Status))
            {
                messageText += "❌ <i>Сессия отменена</i>\n\n";
            }
            else
            {
                messageText += "\n";
                var dateTitle = session.ScheduledAt.FormatMoscowShort();
                buttons.Add(new[]
                {
                    InlineKeyboardButton.WithCallbackData(GetJoinButtonText(session, sessionPlayers.Count, dateTitle), $"join_session:{session.SessionId}"),
                    InlineKeyboardButton.WithCallbackData($"🚪 Выйти {dateTitle}", $"leave_session:{session.SessionId}")
                });

            }
        }

        return (messageText, new InlineKeyboardMarkup(buttons));
    }

    private static string GetJoinButtonText(SessionBatchDto session, int activePlayers, string dateTitle)
    {
        if (session.MaxPlayers.HasValue && activePlayers >= session.MaxPlayers.Value)
        {
            return $"⏳ В лист ожидания {dateTitle}";
        }

        return $"✋ На {dateTitle}";
    }
}
