#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; private const int Cooldown = 30; 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.MarkAsModified(animationFileOption); } // ReSharper disable once MemberCanBeProtected.Global public virtual async Task HandleAnimation() { var animationFileId = (await GetAnimationFileOption()).GetValue(string.Empty); var lastUseOption = await GetLastUseOption(); if (animationFileId.IsNullOrEmpty() || !AnimationMatch.IsMatch(Message!.Text!.ToLower()) || !CanHandle()) return false; if (lastUseOption.GetValue() > DateTime.Now) { _logger.LogInformation("{Name} is on cooldown for Chat {ChatTitle}. Will be available at {Time}", GetAnimationName(), Chat.Title, lastUseOption.GetValue()); return false; } await Bot.SendAnimationAsync(Chat.Id, animationFileId, replyToMessageId: GetMessageIdToReply() ?? Message?.MessageId); lastUseOption.SetValue(DateTime.Now + TimeSpan.FromSeconds(Cooldown)); _db.MarkAsModified(lastUseOption); return true; } private async Task GetAnimationFileOption() { return await _db.UserValues.FindOrCreateOption(Chat.Id, $"{GetAnimationName()}File"); } private async Task GetLastUseOption() { return await _db.UserValues.FindOrCreateOption(Chat.Id, $"{GetAnimationName()}LastUse"); } private async Task CanPunish() { return RepliedUser != null && await Bot.CanPunishMember(Chat, From, RepliedUser); } protected virtual int? GetMessageIdToReply() => Message?.MessageId; } }