public async Task CreateAndScheduleGuildEvent(
            CommandContext context,
            [Description("The channel to announce the event in")]
            DiscordChannel announcementChannel,
            [Description("The role to announce the event to")]
            DiscordRole role,
            [Description("The date to schedule the event for")]
            [RemainingText]
            string datetimeString
            )
        {
            using IBotAccessProvider provider = this.accessBuilder.Build();

            if (!context.User.TryGetDateTimeZone(provider, this.timeZoneProvider, out DateTimeZone schedulerTimeZone))
            {
                await context.RespondAsync(StringConstants.NoTimeZoneErrorMessage);

                return;
            }

            DiscordMember botMember = await context.Guild.GetMemberAsync(context.Client.CurrentUser.Id);

            if (!announcementChannel.PermissionsFor(botMember).HasPermission(Permissions.SendMessages | Permissions.MentionEveryone))
            {
                await context.RespondAsync($"{context.Member.Mention}, I don't have permission to send messages and mention `@everyone` in that channel.");

                return;
            }

            LocalDateTime datetime = Recognizers.RecognizeDateTime(datetimeString, DateTimeV2Type.DateTime)
                                     .First().Values.Select(value => (LocalDateTime)value.Value).OrderBy(key => key).First();
            DiscordMessage msg = await context.RespondAsync($":wave: Hi, {context.User.Mention}! You want to schedule an event for {datetime:g} in your timezone?");

            InteractivityExtension interactivity = context.Client.GetInteractivity();
            Reaction reaction = await interactivity.AddAndWaitForYesNoReaction(msg, context.User);

            if (reaction != Reaction.Yes)
            {
                return;
            }

            await this.AddGuildEventInteractive(context, interactivity, msg);

            GuildEvent selectedEvent = provider.GetAllAssociatedGuildEvents(context.Guild.Id).OrderByDescending(e => e.Id).First();

            Instant      eventDateTime = datetime.InZoneStrictly(schedulerTimeZone).ToInstant();
            DiscordEmbed embed         = new DiscordEmbedBuilder()
                                         .WithAuthor(context.Member.DisplayName, iconUrl: context.Member.AvatarUrl)
                                         .WithDescription(selectedEvent.EventDesc)
                                         .WithTitle(selectedEvent.EventName)
                                         .Build();
            await msg.ModifyAsync($"You have scheduled the following event for {datetime:g} in your time zone to be output in the {announcementChannel.Mention} channel.", embed : embed);

            this.ScheduleEventsForRole(context, announcementChannel, provider, selectedEvent, eventDateTime, role);
        }
        public async Task RandomEventForRole(CommandContext context,
                                             [Description("Role to mention")]
                                             DiscordRole role)
        {
            DiscordMessage msg = await context.RespondAsync(
                $":wave: Hi, {context.User.Mention}! You want to `@everyone` and announce a random event?");

            await msg.CreateReactionAsync(DiscordEmoji.FromName(context.Client, ":regional_indicator_y:"));

            await msg.CreateReactionAsync(DiscordEmoji.FromName(context.Client, ":regional_indicator_n:"));

            InteractivityExtension interactivity = context.Client.GetInteractivity();

            InteractivityResult <MessageReactionAddEventArgs> interactivityResult =
                await interactivity.WaitForReactionAsync(msg, context.User);

            if (interactivityResult.TimedOut ||
                !interactivityResult.Result.Emoji.Equals(
                    DiscordEmoji.FromName(context.Client, ":regional_indicator_y:")))
            {
                DiscordMessage snark = await context.RespondAsync($"{context.User.Mention}, well then why did you get my attention! Thanks for wasting my time. Now I have to clean up your mess.");

                await Task.Delay(5000);

                await context.Channel.DeleteMessagesAsync(new List <DiscordMessage> {
                    msg, snark, context.Message
                });

                return;
            }

            await context.Channel.DeleteMessagesAsync(new List <DiscordMessage> {
                context.Message, msg
            });

            using IBotAccessProvider provider = this.accessBuilder.Build();
            List <GuildEvent>   guildEvents       = provider.GetAllAssociatedGuildEvents(context.Guild.Id).ToList();
            GuildEvent          selectedEvent     = guildEvents[Random.Next(guildEvents.Count)];
            DiscordEmbedBuilder eventEmbedBuilder = new DiscordEmbedBuilder();

            eventEmbedBuilder
            .WithTitle(selectedEvent.EventName)
            .WithDescription(selectedEvent.EventDesc);
            await context.RespondAsync(role.Mention, embed : eventEmbedBuilder.Build());
        }
        private static async Task <GuildEvent> SelectPredefinedEvent(CommandContext context, IBotAccessProvider provider, DiscordMessage msg, InteractivityExtension interactivity, DiscordEmbedBuilder scheduleEmbedBase)
        {
            List <GuildEvent>  guildEvents = provider.GetAllAssociatedGuildEvents(context.Guild.Id).ToList();
            IEnumerable <Page> pages       = GetGuildEventsPages(guildEvents, interactivity, scheduleEmbedBase);
            CustomResult <int> result      = await context.WaitForMessageAndPaginateOnMsg(pages,
                                                                                          PaginationMessageFunction.CreateWaitForMessageWithIntInRange(context.User, context.Channel, 1, guildEvents.Count + 1),
                                                                                          msg : msg
                                                                                          );

            if (result.TimedOut || result.Cancelled)
            {
                DiscordMessage snark = await context.RespondAsync("You never gave me a valid input. Thanks for wasting my time. :triumph:");

                await Task.Delay(5000);

                await context.Channel.DeleteMessagesAsync(new List <DiscordMessage> {
                    msg, snark
                });

                return(null);
            }

            return(guildEvents[result.Result - 1]);
        }
        public async Task RemoveGuildEvent(CommandContext context)
        {
            using IBotAccessProvider provider = this.accessBuilder.Build();
            DiscordMessage msg = await context.RespondAsync(
                $":wave: Hi, {context.User.Mention}! You want to remove an event from your guild list?");

            await msg.CreateReactionAsync(DiscordEmoji.FromName(context.Client, ":regional_indicator_y:"));

            await msg.CreateReactionAsync(DiscordEmoji.FromName(context.Client, ":regional_indicator_n:"));

            InteractivityExtension interactivity = context.Client.GetInteractivity();

            InteractivityResult <MessageReactionAddEventArgs> interactivityResult =
                await interactivity.WaitForReactionAsync(msg, context.User);

            if (interactivityResult.TimedOut ||
                !interactivityResult.Result.Emoji.Equals(
                    DiscordEmoji.FromName(context.Client, ":regional_indicator_y:")))
            {
                DiscordMessage snark = await context.RespondAsync("Well, thanks for wasting my time. Have a good day.");

                await Task.Delay(5000);

                await context.Channel.DeleteMessagesAsync(new List <DiscordMessage> {
                    msg, snark, context.Message
                });

                return;
            }

            DiscordEmbedBuilder removeEventEmbed = new DiscordEmbedBuilder()
                                                   .WithTitle("Select an event to remove by typing: <event number>")
                                                   .WithColor(context.Member.Color);

            Task <(bool, int)> messageValidationAndReturn(MessageCreateEventArgs messageE)
            {
                if (messageE.Author.Equals(context.User) && int.TryParse(messageE.Message.Content, out int eventToChoose))
                {
                    return(Task.FromResult((true, eventToChoose)));
                }
                else
                {
                    return(Task.FromResult((false, -1)));
                }
            }

            List <GuildEvent> guildEvents = provider.GetAllAssociatedGuildEvents(context.Guild.Id).ToList();

            await msg.DeleteAllReactionsAsync();

            CustomResult <int> result = await context.WaitForMessageAndPaginateOnMsg(
                GetGuildEventsPages(guildEvents, interactivity, removeEventEmbed),
                messageValidationAndReturn,
                msg : msg);

            if (result.TimedOut || result.Cancelled)
            {
                DiscordMessage snark = await context.RespondAsync("You never gave me a valid input. Thanks for wasting my time. :triumph:");

                await Task.Delay(5000);

                await context.Channel.DeleteMessagesAsync(new List <DiscordMessage> {
                    msg, snark
                });

                return;
            }

            GuildEvent selectedEvent = guildEvents[result.Result - 1];

            provider.DeleteGuildEvent(selectedEvent);
            await msg.ModifyAsync($"You have deleted the \"{selectedEvent.EventName}\" event from the guild", embed : null);
        }