public async Task HandleAwardedMessageDeleted(MessageAwardQueueItem awardItem)
        {
            var messageId = awardItem.DiscordMessageId;

            var channel = awardItem.DiscordChannel !;
            var guild   = channel.Guild;

            var awardChannel = await _discordResolver.ResolveChannel(guild, _options.AwardChannelId);

            if (awardChannel == null)
            {
                _logger.LogDebug("Could not resolve awards channel");
                return;
            }

            var awardMessage = await _awardMessageRepo.GetAwardMessageByAwardedMessageId(awardChannel.Id, messageId);

            if (awardMessage == null)
            {
                _logger.LogDebug($"Message ({messageId}) does not exist in award channel");
                return;
            }

            await _awardMessageRepo.DeleteAwardMessage(awardMessage.Id);
        }
        public async Task HandleAwardMessageUpdated(MessageAwardQueueItem awardItem)
        {
            var partialMessage = awardItem.DiscordMessage;

            var message = await _discordResolver.ResolveMessage(partialMessage.Channel, partialMessage.Id);

            if (message == null)
            {
                _logger.LogDebug("Could not resolve message");
                return;
            }

            var channel = message.Channel;
            var guild   = channel.Guild;

            var messageAuthor = await _discordResolver.ResolveGuildMember(guild, message.Author.Id);

            if (messageAuthor == null)
            {
                _logger.LogDebug("Could not resolve message author");
                return;
            }

            var awardChannel = await _discordResolver.ResolveChannel(guild, _options.AwardChannelId);

            if (awardChannel == null)
            {
                _logger.LogDebug("Could not resolve awards channel");
                return;
            }

            uint awardReactionCount = await GetAwardReactionCount(message, messageAuthor);

            var hasAwards = awardReactionCount > 0;

            if (!hasAwards)
            {
                _logger.LogDebug($"Updated message has no awards");
                return;
            }

            var awardMessage = await _awardMessageRepo.GetAwardMessageByOriginalMessageId(awardChannel.Id, message.Id);

            if (awardMessage == null)
            {
                _logger.LogDebug($"Could not find ({message.Id}) in the database");
                return;
            }

            await UpdateAwardedMessageEmbed(awardChannel, awardMessage.AwardedMessageId, message, messageAuthor);
        }
        public async Task HandleAwardChange(MessageAwardQueueItem awardItem)
        {
            // TODO optimize by resolving full message only if it will be posted
            var partialMessage = awardItem.DiscordMessage;

            var message = await _discordResolver.ResolveMessage(partialMessage.Channel, partialMessage.Id);

            if (message == null)
            {
                _logger.LogDebug("Could not resolve message");
                return;
            }

            var channel = message.Channel;
            var guild   = channel.Guild;

            var messageAuthor = await _discordResolver.ResolveGuildMember(guild, message.Author.Id);

            if (messageAuthor == null)
            {
                _logger.LogDebug("Could not resolve message author");
                return;
            }

            var awardChannel = await _discordResolver.ResolveChannel(guild, _options.AwardChannelId);

            if (awardChannel == null)
            {
                _logger.LogDebug("Could not resolve awards channel");
                return;
            }

            uint awardReactionCount = await GetAwardReactionCount(message, messageAuthor);

            var hasEnoughAwards = awardReactionCount >= _options.RequiredAwardCount;

            var awardMessage = await _awardMessageRepo.GetAwardMessageByOriginalMessageId(awardChannel.Id, message.Id);

            _logger.LogDebug($"Message has {awardReactionCount} awards");

            if (awardMessage == null)
            {
                _logger.LogDebug($"Message ({message.Id}) does not exist in the database");

                if (!hasEnoughAwards)
                {
                    _logger.LogDebug($"Not enough awards. {awardReactionCount} / {_options.RequiredAwardCount}");
                    return;
                }

                var postedMessage = await PostAwardedMessage(awardChannel, message, messageAuthor, awardReactionCount);

                await _awardMessageRepo.CreateAwardMessage(message.Id, message.ChannelId, postedMessage.Id, awardChannel.Id, messageAuthor.Id, awardReactionCount);
            }
            else
            {
                _logger.LogDebug($"Message ({message.Id}) exists in award channel");

                // TODO keep track if message was removed from award channels
                // so it's handled gracefully i.e. not throw an error
                // when it tries to update a removed message
                await UpdateAwardedMessageText(awardChannel, awardMessage.AwardedMessageId, awardReactionCount);

                await _awardMessageRepo.UpdateAwardCount(awardMessage.Id, awardReactionCount);
            }
        }