public async Task <bool> TryDeleteAsync(string teamId, string name, string deletedByUserId)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("The supplied name cannot be null or whitespace.", nameof(name));
            }

            var entity = await NaviBotContext.Tags.FirstOrDefaultAsync(x
                                                                       => x.TeamId == teamId &&
                                                                       x.Name == name.ToLower() &&
                                                                       x.DeleteActionId == null);

            if (entity is null)
            {
                return(false);
            }

            var deleteAction = new TagActionEntity()
            {
                TeamId      = entity.TeamId,
                Created     = DateTimeOffset.Now,
                Type        = TagActionType.TagDeleted,
                CreatedById = deletedByUserId,
                OldTagId    = entity.Id,
            };

            await NaviBotContext.TagActions.AddAsync(deleteAction);

            await NaviBotContext.SaveChangesAsync();

            entity.DeleteActionId = deleteAction.Id;
            await NaviBotContext.SaveChangesAsync();

            return(true);
        }
        public async Task <bool> TryModifyAsync(string teamId, string name, string modifiedByUserId, Action <TagMutationData> modifyAction)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("The supplied name cannot be null or whitespace.", nameof(name));
            }

            if (modifyAction is null)
            {
                throw new ArgumentNullException(nameof(modifyAction));
            }

            var oldTag = await NaviBotContext.Tags.FirstOrDefaultAsync(x
                                                                       => x.TeamId == teamId &&
                                                                       x.Name == name.ToLower() &&
                                                                       x.DeleteActionId == null);

            if (oldTag is null)
            {
                return(false);
            }

            var action = new TagActionEntity()
            {
                TeamId      = teamId,
                Type        = TagActionType.TagModified,
                Created     = DateTimeOffset.Now,
                CreatedById = modifiedByUserId,
                OldTagId    = oldTag.Id,
            };

            await NaviBotContext.TagActions.AddAsync(action);

            await NaviBotContext.SaveChangesAsync();

            var newTagData = TagMutationData.FromEntity(oldTag);

            modifyAction(newTagData);

            var newTag = newTagData.ToEntity();

            newTag.CreateActionId = action.Id;

            await NaviBotContext.Tags.AddAsync(newTag);

            await NaviBotContext.SaveChangesAsync();

            action.NewTagId       = newTag.Id;
            oldTag.DeleteActionId = action.Id;

            await NaviBotContext.SaveChangesAsync();

            return(true);
        }
        /// <inheritdoc />
        public async Task <long> CreateAsync(TagCreationData data)
        {
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            var entity = data.ToEntity();

            await NaviBotContext.Tags.AddAsync(entity);

            await NaviBotContext.SaveChangesAsync();

            entity.CreateAction.NewTagId = entity.Id;
            await NaviBotContext.SaveChangesAsync();

            return(entity.Id);
        }