private async Task TryBuyInternalAsync(CommandContext ctx, ChickenType type, string name)
            {
                if (string.IsNullOrWhiteSpace(name))
                {
                    throw new InvalidCommandUsageException("Name for your chicken is missing.");
                }

                if (name.Length < 2 || name.Length > 30)
                {
                    throw new InvalidCommandUsageException("Name cannot be shorter than 2 and longer than 30 characters.");
                }

                if (!name.All(c => char.IsLetterOrDigit(c) || char.IsWhiteSpace(c)))
                {
                    throw new InvalidCommandUsageException("Name cannot contain characters that are not letters or digits.");
                }

                if (!(Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id) is null))
                {
                    throw new CommandFailedException("You already own a chicken!");
                }

                if (!await ctx.WaitForBoolReplyAsync($"{ctx.User.Mention}, are you sure you want to buy a chicken for {Formatter.Bold(Chicken.Price(type).ToString())} {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"}?"))
                {
                    return;
                }

                using (DatabaseContext db = this.Database.CreateContext()) {
                    if (!await db.TryDecreaseBankAccountAsync(ctx.User.Id, ctx.Guild.Id, Chicken.Price(type)))
                    {
                        throw new CommandFailedException($"You do not have enough {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"} to buy a chicken ({Chicken.Price(type)} needed)!");
                    }

                    ChickenStats stats = Chicken.StartingStats[type];
                    db.Chickens.Add(new DatabaseChicken {
                        GuildId     = ctx.Guild.Id,
                        MaxVitality = stats.BareMaxVitality,
                        Name        = name,
                        Strength    = stats.BareStrength,
                        UserId      = ctx.User.Id,
                        Vitality    = stats.BareVitality
                    });

                    await db.SaveChangesAsync();
                }

                await this.InformAsync(ctx, StaticDiscordEmoji.Chicken, $"{ctx.User.Mention} bought a chicken named {Formatter.Bold(name)}");
            }
        public static Task AddChickenAsync(this DBService db, ulong uid, ulong gid, string name, ChickenStats stats)
        {
            return(db.ExecuteCommandAsync(cmd => {
                cmd.CommandText = "INSERT INTO gf.chickens(uid, gid, name, strength, vitality, max_vitality) VALUES (@uid, @gid, @name, @strength, @vitality, @max_vitality) ON CONFLICT DO NOTHING;";
                cmd.Parameters.Add(new NpgsqlParameter <long>("uid", (long)uid));
                cmd.Parameters.Add(new NpgsqlParameter <long>("gid", (long)gid));
                cmd.Parameters.Add(new NpgsqlParameter <int>("strength", stats.BareStrength));
                cmd.Parameters.Add(new NpgsqlParameter <int>("vitality", stats.BareVitality));
                cmd.Parameters.Add(new NpgsqlParameter <int>("max_vitality", stats.BareMaxVitality));
                if (string.IsNullOrWhiteSpace(name))
                {
                    cmd.Parameters.Add(new NpgsqlParameter <string>("name", null));
                }
                else
                {
                    cmd.Parameters.Add(new NpgsqlParameter <string>("name", name));
                }

                return cmd.ExecuteNonQueryAsync();
            }));
        }