/// <summary>
        /// The MessageReceived checks to see if a message was sent in the commissions channel and, if so, runs it on a query to check if the user has sent
        /// a commission on an earlier period of time. If so, it deletes the commission if possible and warns the user of posting too quick commissions.
        /// </summary>
        /// <param name="SocketMessage">The SocketMessage contains information of the message that was sent, including the author, and can be used to remove the message.</param>
        /// <returns>A <c>Task</c> object, which can be awaited until this method completes successfully.</returns>

        public async Task MessageReceived(SocketMessage SocketMessage)
        {
            // We first check to see if the channel is in the commissions corner and not from a bot to continue.
            if (!ChannelCooldownConfiguration.ChannelCooldowns.ContainsKey(SocketMessage.Channel.Id) || SocketMessage.Author.IsBot)
            {
                return;
            }

            // We then try pull the cooldown from the database to see if the user and channel ID both exist as a token.
            Cooldown Cooldown = CooldownDB.Cooldowns.Find($"{SocketMessage.Author.Id}{SocketMessage.Channel.Id}");

            if (Cooldown != null)
            {
                // We then check to see if the cooldown is expired. If so, we set the new time.
                if (Cooldown.TimeOfCooldown + ChannelCooldownConfiguration.ChannelCooldowns[SocketMessage.Id]["CooldownTime"] > DateTimeOffset.UtcNow.ToUnixTimeSeconds())
                {
                    // We then check to see if the cooldown is in the grace-period. This is a period of time where the user can send multiple messages. Once this cooldown has ended we warn the user.
                    if (Cooldown.TimeOfCooldown + ChannelCooldownConfiguration.ChannelCooldowns[SocketMessage.Id]["GracePeriod"] < DateTimeOffset.UtcNow.ToUnixTimeSeconds())
                    {
                        DateTime CooldownTime = DateTime.UnixEpoch.AddSeconds(Cooldown.TimeOfCooldown);

                        // We first attempt to delete the message. This may throw an error.
                        await SocketMessage.DeleteAsync();

                        // We then warn the user that they are not allowed to post a commission, as they have reached their maximum allotted time.
                        await BuildEmbed(EmojiEnum.Love)
                        .WithTitle($"Haiya, {SocketMessage.Author.Username}.")
                        .WithDescription($"Just a friendly reminder you are only allowed to post in this channel every" +
                                         $" {TimeSpan.FromSeconds(ChannelCooldownConfiguration.ChannelCooldowns[SocketMessage.Id]["CooldownTime"]).TotalDays} days. " +
                                         $"Please take a lookie over the channel pins regarding the regulations of this channel if you haven't already <3")
                        .AddField("Last Message Sent:", $"{CooldownTime.ToLongTimeString()}, {CooldownTime.ToLongDateString()}")
                        .WithFooter($"Times are in {(TimeZoneInfo.Local.IsDaylightSavingTime(CooldownTime) ? TimeZoneInfo.Local.DaylightName : TimeZoneInfo.Local.StandardName)}.")
                        .WithCurrentTimestamp()
                        .SendEmbed(SocketMessage.Author, SocketMessage.Channel as ITextChannel);
                    }
                }
                else
                {
                    // If the commission has expired we set the new cooldown.
                    Cooldown.TimeOfCooldown = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

                    CooldownDB.SaveChanges();
                }
            }
            else
            {
                // If the user has not posted a commission before we add a new commission cooldown to the database.
                CooldownDB.Cooldowns.Add(
                    new Cooldown()
                {
                    Token          = $"{SocketMessage.Author.Id}{SocketMessage.Channel.Id}",
                    TimeOfCooldown = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
                }
                    );

                CooldownDB.SaveChanges();
            }
        }
        /// <summary>
        /// The CheckPermissionsAsync is an overriden method from its superclass, which checks
        /// to see if a command can be run by a user through the cooldown of the command in the database.
        /// </summary>
        /// <param name="CommandContext">The Context is used to find the channel that has had the command run in.</param>
        /// <param name="CommandInfo">The CommandInfo is used to find the name of the command that has been run.</param>
        /// <param name="ServiceProvider">The ServiceProvider is used to get the database of cooldowns.</param>
        /// <returns>The result of the checked permission, returning successful if it is able to be run or an error if not.
        /// This error is then thrown to the Command Handler Service to log to the user.</returns>

        public override async Task <PreconditionResult> CheckPermissionsAsync(ICommandContext CommandContext, CommandInfo CommandInfo, IServiceProvider ServiceProvider)
        {
            if (ServiceProvider.GetService <BotConfiguration>() == null)
            {
                return(PreconditionResult.FromSuccess());
            }

            if (ServiceProvider.GetRequiredService <BotConfiguration>().BotChannels.Contains(CommandContext.Channel.Id))
            {
                return(PreconditionResult.FromSuccess());
            }

            CooldownDB CooldownDB = ServiceProvider.GetRequiredService <CooldownDB>();

            Cooldown Cooldown = CooldownDB.Cooldowns.Find($"{CommandInfo.Name}{CommandContext.Channel.Id}");

            if (Cooldown != null)
            {
                if (Cooldown.TimeOfCooldown + CooldownTimer < DateTimeOffset.UtcNow.ToUnixTimeSeconds())
                {
                    CooldownDB.Remove(Cooldown);
                    CooldownDB.SaveChanges();
                }
                else
                {
                    DateTime Time = DateTime.UnixEpoch.AddSeconds(Cooldown.TimeOfCooldown + CooldownTimer);

                    await new EmbedBuilder().BuildEmbed(EmojiEnum.Wut, ServiceProvider.GetService <BotConfiguration>())
                    .WithAuthor($"Hiya, {CommandContext.User.Username}!")
                    .WithTitle($"Please wait {Time.Humanize()} until you are able to use this command.")
                    .WithDescription("Thanks for your patience, we really do appreciate it. <3")
                    .SendEmbed(CommandContext.User, CommandContext.Channel as ITextChannel);

                    return(PreconditionResult.FromError(""));
                }
            }

            CooldownDB.Add(
                new Cooldown()
            {
                Token          = $"{CommandInfo.Name}{CommandContext.Channel.Id}",
                TimeOfCooldown = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
            }
                );

            CooldownDB.SaveChanges();

            return(PreconditionResult.FromSuccess());
        }
        public async Task CooldownCommand(EntryType EntryType, IUser User, ITextChannel TextChannel)
        {
            switch (EntryType)
            {
            case EntryType.Issue:
                Cooldown IssueCooldown = CooldownDB.Cooldowns.Find($"{User.Id}{TextChannel.Id}");

                if (IssueCooldown != null)
                {
                    if (IssueCooldown.TimeOfCooldown + CommissionCooldownConfiguration.ChannelCooldowns[TextChannel.Id]["CooldownTime"] < DateTimeOffset.UtcNow.ToUnixTimeSeconds())
                    {
                        CooldownDB.Cooldowns.Remove(IssueCooldown);
                        CooldownDB.SaveChanges();
                    }
                    else
                    {
                        DateTime CooldownTime = DateTime.UnixEpoch.AddSeconds(IssueCooldown.TimeOfCooldown);

                        await BuildEmbed(EmojiEnum.Love)
                        .WithTitle($"Unable To Issue {TextChannel} Cooldown.")
                        .WithDescription($"Haiya! The user {User.GetUserInformation()} seems to already be on cooldown. " +
                                         $"This cooldown in was applied on {CooldownTime.ToLongDateString()} at {CooldownTime.ToLongTimeString()}.")
                        .WithCurrentTimestamp()
                        .SendEmbed(Context.Channel);

                        return;
                    }
                }

                Cooldown NewCooldown = new () {
                    Token          = $"{User.Id}{TextChannel.Id}",
                    TimeOfCooldown = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
                };

                CooldownDB.Cooldowns.Add(NewCooldown);

                CooldownDB.SaveChanges();

                DateTime NewCooldownTime = DateTime.UnixEpoch.AddSeconds(NewCooldown.TimeOfCooldown);

                await BuildEmbed(EmojiEnum.Love)
                .WithTitle($"Added {TextChannel} Cooldown!")
                .WithDescription($"Successfully added cooldown to {User.GetUserInformation()} " +
                                 $"at {NewCooldownTime.ToLongTimeString()}, {NewCooldownTime.ToLongDateString()}.")
                .WithCurrentTimestamp()
                .SendDMAttachedEmbed(Context.Channel, BotConfiguration, User,
                                     BuildEmbed(EmojiEnum.Love)
                                     .WithTitle($"{TextChannel} Cooldown Issued.")
                                     .WithDescription($"Haiya! We've given you a cooldown set at {NewCooldownTime.ToLongTimeString()}, {NewCooldownTime.ToLongDateString()}. <3")
                                     .WithCurrentTimestamp()
                                     );

                break;

            case EntryType.Revoke:
                Cooldown RevokeCooldown = CooldownDB.Cooldowns.Find($"{User.Id}{TextChannel.Id}");

                if (RevokeCooldown != null)
                {
                    CooldownDB.Cooldowns.Remove(RevokeCooldown);
                    CooldownDB.SaveChanges();

                    DateTime CooldownTime = DateTime.UnixEpoch.AddSeconds(RevokeCooldown.TimeOfCooldown);

                    await BuildEmbed(EmojiEnum.Unknown)
                    .WithTitle($"Removed {TextChannel} Cooldown!")
                    .WithDescription($"Successfully removed cooldown from {User.GetUserInformation()}, " +
                                     $"of whose cooldown used to be {CooldownTime.ToLongTimeString()}, {CooldownTime.ToLongDateString()}.")
                    .WithCurrentTimestamp()
                    .SendDMAttachedEmbed(Context.Channel, BotConfiguration, User, BuildEmbed(EmojiEnum.Love)
                                         .WithTitle($"{TextChannel} Cooldown Revoked.")
                                         .WithDescription($"Haiya! We've revoked your cooldown set at {CooldownTime.ToLongTimeString()}, " +
                                                          $"{CooldownTime.ToLongDateString()}. You should now be able to re-send your informtion into the channel. <3")
                                         .WithCurrentTimestamp()
                                         );
                }
                else
                {
                    await BuildEmbed(EmojiEnum.Annoyed)
                    .WithTitle($"Unable To Remove {TextChannel} Cooldown.")
                    .WithDescription($"Haiya! I was unable to remove the cooldown from {User.GetUserInformation()}. " +
                                     $"Are you sure this is the correct ID or that they have a cooldown lain against them?")
                    .WithCurrentTimestamp()
                    .SendEmbed(Context.Channel);
                }

                break;

            default:
                await BuildEmbed(EmojiEnum.Annoyed)
                .WithTitle($"Unable To Modify {TextChannel} Cooldown")
                .WithDescription($"The argument {EntryType} does not exist as an option to use on this command!")
                .SendEmbed(Context.Channel);

                break;
            }
        }