#nullable enable using System; using System.Text.RegularExpressions; using System.Threading.Tasks; using BotFramework; using Castle.Core.Internal; using Kruzya.TelegramBot.Core.Data; using Kruzya.TelegramBot.Core.Extensions; using Microsoft.Extensions.Logging; using Telegram.Bot; using Telegram.Bot.Types; namespace West.Entertainment.Handler.Fun { public abstract class AbstractAnimationReply : BotEventHandler { private readonly CoreContext _db; private readonly ILogger _logger; protected virtual TimeSpan Cooldown => TimeSpan.FromMinutes(new Random().Next(10, 1337)); protected Message? Message => RawUpdate.Message; private User? RepliedUser => Message?.ReplyToMessage?.From; protected abstract Regex AnimationMatch { get; } protected AbstractAnimationReply(CoreContext db, ILogger logger) { _db = db; _logger = logger; } protected abstract string GetAnimationName(); protected virtual bool CanHandle() => true; protected async Task HandleSetAnimation() { var animation = Message?.ReplyToMessage?.Animation; if (await CanPunish() || animation == null) return; var animationFileOption = await GetAnimationFileOption(); animationFileOption.SetValue(animation.FileId); _db.AddOrUpdate(animationFileOption); } // ReSharper disable once MemberCanBeProtected.Global public virtual async Task HandleAnimation() { var text = Message!.Text!.ToLower(); if (!AnimationMatch.IsMatch(text.ToLower()) || text.StartsWith("/set") || !CanHandle()) return false; var animationFileId = (await GetAnimationFileOption()).GetValue(string.Empty); var nextUseOption = await GetNextUseOption(); _logger.LogDebug("Animation: {Text}, ToLower: {ToLowerText}", Message!.Text, Message!.Text!.ToLower()); if (animationFileId.IsNullOrEmpty()) return false; var nextUseDt = nextUseOption.GetValue(); if (nextUseDt > DateTime.Now) { _logger.LogInformation("{Name} is on cooldown for chat \"{ChatTitle}\". Will be available at {Time}", GetAnimationName(), Chat.Title, nextUseDt); return false; } await Bot.SendAnimationAsync(Chat.Id, animationFileId, replyToMessageId: GetMessageIdToReply() ?? Message?.MessageId); nextUseOption.SetValue(DateTime.Now + Cooldown); _db.AddOrUpdate(nextUseOption); return true; } private async Task GetAnimationFileOption() { return await _db.UserValues.FindOrCreateOption(Chat.Id, $"{GetAnimationName()}File"); } private async Task GetNextUseOption() { return await _db.UserValues.FindOrCreateOption(Chat.Id, $"{GetAnimationName()}NextUse"); } private async Task CanPunish() { return RepliedUser != null && await Bot.CanPunishMember(Chat, From, RepliedUser); } protected virtual int? GetMessageIdToReply() => Message?.MessageId; } }