using System.Security.Cryptography; using Microsoft.Extensions.Configuration; using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using UserOfTheDayBot.Data; using UserOfTheDayBot.Model; namespace UserOfTheDayBot.Services; public class BotService { private readonly ITelegramBotClient _botClient; private readonly IUserRepository _userRepository; private readonly IUserOfTheDayRepository _userOfTheDayRepository; public BotService(IConfiguration configuration, IUserRepository userRepository, IUserOfTheDayRepository userOfTheDayRepository) { _botClient = new TelegramBotClient(configuration["BotSettings:BotToken"] ?? Environment.GetEnvironmentVariable("BotSettings_BotToken")); _userRepository = userRepository; _userOfTheDayRepository = userOfTheDayRepository; } public async Task HandleUpdateAsync(Update update, CancellationToken cancellationToken) { if (update.Type == UpdateType.Message && update.Message?.Text != null) { var message = update.Message; if (message.Text.StartsWith("/help")) { await _botClient.SendTextMessageAsync(message.Chat.Id, "Уйди. Попробуйте /reg", cancellationToken: cancellationToken); } else if (message.Text.StartsWith("/reg")) { await RegisterUserAsync(message, cancellationToken); } else if (message.Text.StartsWith("/useroftheday")) { await HandleUserOfTheDayCommandAsync(message, UserOfTheDayType.UserOfTheDay, cancellationToken); } else if (message.Text.StartsWith("/loser")) { await HandleUserOfTheDayCommandAsync(message, UserOfTheDayType.LoserOfTheDay, cancellationToken); } else if (message.Text.StartsWith("/stat")) { await HandleStatCommandAsync(message, cancellationToken); } } } private async Task RegisterUserAsync(Message message, CancellationToken cancellationToken) { try { int rowsAffected = await _userRepository.RegisterUserAsync(message.Chat.Id, message.From.Id, message.From.FirstName); if (rowsAffected > 0) { await _botClient.SendTextMessageAsync(message.Chat.Id, "Вы успешно зарегистрированы!", cancellationToken: cancellationToken); } else { await _botClient.SendTextMessageAsync(message.Chat.Id, "Вы уже зарегистрированы.", cancellationToken: cancellationToken); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); await _botClient.SendTextMessageAsync(message.Chat.Id, "Произошла ошибка при регистрации. Попробуйте позже.", cancellationToken: cancellationToken); } } private async Task HandleUserOfTheDayCommandAsync(Message message, UserOfTheDayType type, CancellationToken cancellationToken) { try { var today = message.Date.Date; Console.WriteLine(message.Date); var chatId = message.Chat.Id; if (await _userOfTheDayRepository.IsUserOfTheDaySelectedAsync(chatId, today, type)) { var responseMessage = type == UserOfTheDayType.UserOfTheDay ? "Пользователь дня уже выбран." : "Пидор дня уже выбран."; await _botClient.SendTextMessageAsync(chatId, responseMessage, cancellationToken: cancellationToken); return; } var selectedUser = await SelectUserOfTheDayAsync(chatId, today, type); if (selectedUser.userId is not null) { var responseMessage = type == UserOfTheDayType.UserOfTheDay ? "Пользователь дня" : "Пидор дня"; await _botClient.SendTextMessageAsync(chatId, $"{responseMessage}: {selectedUser.userName}", cancellationToken: cancellationToken); } else { await _botClient.SendTextMessageAsync(chatId, "В чате нет зарегистрированных пользователей.", cancellationToken: cancellationToken); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); await _botClient.SendTextMessageAsync(message.Chat.Id, "Произошла ошибка при выборе пользователя дня. Попробуйте позже.", cancellationToken: cancellationToken); } } private async Task<(long? userId, string userName)> SelectUserOfTheDayAsync(long chatId, DateTime date, UserOfTheDayType type) { var users = (await _userRepository.GetUsersWithNamesAsync(chatId)).ToList(); if (users.Any()) { using (var rng = RandomNumberGenerator.Create()) { while (users.Count > 0) { var randomIndex = GetRandomIndex(users.Count, rng); var selectedUser = users[randomIndex]; if (!await _userOfTheDayRepository.IsUserAlreadySelectedAsync(chatId, date, selectedUser.userId)) { await _userOfTheDayRepository.RecordUserOfTheDayAsync(chatId, selectedUser.userId, date, type); return (selectedUser.userId, selectedUser.userName); } users.RemoveAt(randomIndex); } } } return default; } private async Task HandleStatCommandAsync(Message message, CancellationToken cancellationToken) { try { var chatId = message.Chat.Id; var stats = await _userOfTheDayRepository.GetUserStatisticsAsync(chatId); if (stats.Any()) { var userOfTheDaySection = "Пользователь дня:\n"; var loserOfTheDaySection = "Пидор дня:\n"; var sortedUserOfTheDay = stats.OrderByDescending(x => x.Value.userOfTheDayCount); var sortedLoserOfTheDay = stats.OrderByDescending(x => x.Value.loserOfTheDayCount); foreach (var stat in sortedUserOfTheDay) { userOfTheDaySection += $"{stat.Key.userName}: {stat.Value.userOfTheDayCount} раз(а)\n"; } foreach (var stat in sortedLoserOfTheDay) { loserOfTheDaySection += $"{stat.Key.userName}: {stat.Value.loserOfTheDayCount} раз(а)\n"; } var response = userOfTheDaySection + "\n" + loserOfTheDaySection; await _botClient.SendTextMessageAsync(chatId, response, cancellationToken: cancellationToken); } else { await _botClient.SendTextMessageAsync(chatId, "Нет данных о пользователях.", cancellationToken: cancellationToken); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); await _botClient.SendTextMessageAsync(message.Chat.Id, "Произошла ошибка при получении статистики. Попробуйте позже.", cancellationToken: cancellationToken); } } private static int GetRandomIndex(int max, RandomNumberGenerator rng) { var buffer = new byte[4]; rng.GetBytes(buffer); var randomValue = BitConverter.ToUInt32(buffer, 0); return (int)(randomValue % max); } }