import type Discord from "discord.js";
import {
    ActionRowBuilder,
    AnySelectMenuInteraction,
    APIMessageComponentEmoji,
    ButtonBuilder,
    ButtonInteraction,
    ButtonStyle,
    ChannelSelectMenuBuilder,
    ChannelSelectMenuInteraction,
    CommandInteraction,
    Message,
    ModalBuilder,
    RoleSelectMenuBuilder,
    RoleSelectMenuInteraction,
    StringSelectMenuBuilder,
    StringSelectMenuInteraction,
    StringSelectMenuOptionBuilder,
    TextInputBuilder,
    TextInputStyle,
    UserSelectMenuBuilder,
    UserSelectMenuInteraction
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js";
import { LoadingEmbed } from "../../utils/defaults.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
import listToAndMore from "../../utils/listToAndMore.js";

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder.setName("automod").setDescription("Setting for automatic moderation features");

const emojiFromBoolean = (bool: boolean, id?: string) =>
    bool ? getEmojiByName("CONTROL.TICK", id) : getEmojiByName("CONTROL.CROSS", id);

const toSelectMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    ids: string[],
    type: "member" | "role" | "channel",
    title: string
): Promise<string[]> => {
    const back = new ActionRowBuilder<ButtonBuilder>().addComponents(
        new ButtonBuilder()
            .setCustomId("back")
            .setLabel("Back")
            .setStyle(ButtonStyle.Secondary)
            .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji)
    );
    let closed;
    do {
        let render: string[] = [];
        let mapped: string[] = [];
        let menu: UserSelectMenuBuilder | RoleSelectMenuBuilder | ChannelSelectMenuBuilder;
        switch (type) {
            case "member": {
                menu = new UserSelectMenuBuilder().setCustomId("user").setPlaceholder("Select users").setMaxValues(25);
                mapped = await Promise.all(
                    ids.map(async (id) => {
                        return (await client.users.fetch(id).then((user) => user.tag)) || "Unknown User";
                    })
                );
                render = ids.map((id) => client.logger.renderUser(id));
                break;
            }
            case "role": {
                menu = new RoleSelectMenuBuilder().setCustomId("role").setPlaceholder("Select roles").setMaxValues(25);
                mapped = await Promise.all(
                    ids.map(async (id) => {
                        return await interaction.guild!.roles.fetch(id).then((role) => role?.name ?? "Unknown Role");
                    })
                );
                render = ids.map((id) => client.logger.renderRole(id, interaction.guild!));
                break;
            }
            case "channel": {
                menu = new ChannelSelectMenuBuilder()
                    .setCustomId("channel")
                    .setPlaceholder("Select channels")
                    .setMaxValues(25);
                mapped = await Promise.all(
                    ids.map(async (id) => {
                        return await interaction
                            .guild!.channels.fetch(id)
                            .then((channel) => channel?.name ?? "Unknown Role");
                    })
                );
                render = ids.map((id) => client.logger.renderChannel(id));
                break;
            }
        }
        const removeOptions = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("remove")
                .setPlaceholder("Remove")
                .addOptions(
                    mapped.map((name, i) => new StringSelectMenuOptionBuilder().setLabel(name).setValue(ids[i]!))
                )
                .setDisabled(ids.length === 0)
        );

        const embed = new EmojiEmbed()
            .setTitle(title)
            .setEmoji(getEmojiByName("GUILD.SETTINGS.GREEN"))
            .setDescription(`Select ${type}s:\n\nCurrent:\n` + (render.length > 0 ? render.join("\n") : "None"))
            .setStatus("Success");
        const components: ActionRowBuilder<
            | StringSelectMenuBuilder
            | ButtonBuilder
            | ChannelSelectMenuBuilder
            | UserSelectMenuBuilder
            | RoleSelectMenuBuilder
        >[] = [new ActionRowBuilder<typeof menu>().addComponents(menu)];
        if (ids.length > 0) components.push(removeOptions);
        components.push(back);

        await interaction.editReply({ embeds: [embed], components: components });

        let i: AnySelectMenuInteraction | ButtonInteraction;
        try {
            i = await m.awaitMessageComponent({ filter: (i) => i.user.id === interaction.user.id, time: 300000 });
        } catch (e) {
            closed = true;
            continue;
        }

        if (i.isButton()) {
            await i.deferUpdate();
            if (i.customId === "back") {
                closed = true;
                break;
            }
        } else if (i.isStringSelectMenu()) {
            await i.deferUpdate();
            if (i.customId === "remove") {
                ids = ids.filter((id) => id !== (i as StringSelectMenuInteraction).values[0]);
                if (ids.length === 0) {
                    menu.data.disabled = true;
                }
            }
        } else {
            await i.deferUpdate();
            if (i.customId === "user") {
                ids = ids.concat((i as UserSelectMenuInteraction).values);
            } else if (i.customId === "role") {
                ids = ids.concat((i as RoleSelectMenuInteraction).values);
            } else if (i.customId === "channel") {
                ids = ids.concat((i as ChannelSelectMenuInteraction).values);
            }
        }
    } while (!closed);
    return ids;
};

const imageMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    current: {
        NSFW: boolean;
        size: boolean;
    }
): Promise<{ NSFW: boolean; size: boolean }> => {
    let closed = false;
    do {
        const options = new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId("back")
                .setLabel("Back")
                .setStyle(ButtonStyle.Secondary)
                .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("nsfw")
                .setLabel("NSFW")
                .setStyle(current.NSFW ? ButtonStyle.Success : ButtonStyle.Danger)
                .setEmoji(emojiFromBoolean(current.NSFW, "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("size")
                .setLabel("Size")
                .setStyle(current.size ? ButtonStyle.Success : ButtonStyle.Danger)
                .setEmoji(emojiFromBoolean(current.size, "id") as APIMessageComponentEmoji)
        );

        const embed = new EmojiEmbed()
            .setTitle("Image Settings")
            .setStatus("Success")
            // .setEmoji("")  // TODO
            .setDescription(
                `${emojiFromBoolean(current.NSFW)} **NSFW**\n` + `${emojiFromBoolean(current.size)} **Size**\n`
            );

        await interaction.editReply({ embeds: [embed], components: [options] });

        let i: ButtonInteraction;
        try {
            i = (await m.awaitMessageComponent({
                filter: (i) => interaction.user.id === i.user.id && i.message.id === m.id,
                time: 300000
            })) as ButtonInteraction;
        } catch (e) {
            return current;
        }
        await i.deferUpdate();
        switch (i.customId) {
            case "back": {
                closed = true;
                break;
            }
            case "nsfw": {
                current.NSFW = !current.NSFW;
                break;
            }
            case "size": {
                current.size = !current.size;
                break;
            }
        }
    } while (!closed);
    return current;
};

const wordMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    current: {
        enabled: boolean;
        words: { strict: string[]; loose: string[] };
        allowed: { users: string[]; roles: string[]; channels: string[] };
    }
): Promise<{
    enabled: boolean;
    words: { strict: string[]; loose: string[] };
    allowed: { users: string[]; roles: string[]; channels: string[] };
}> => {
    let closed = false;
    do {
        const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId("back")
                .setLabel("Back")
                .setStyle(ButtonStyle.Secondary)
                .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("enabled")
                .setLabel("Enabled")
                .setStyle(current.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
                .setEmoji(emojiFromBoolean(current.enabled, "id") as APIMessageComponentEmoji)
        );

        const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("edit")
                .setPlaceholder("Edit... ")
                .addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Words")
                        .setDescription("Edit your list of words to filter")
                        .setValue("words"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Allowed Users")
                        .setDescription("Users who will be unaffected by the word filter")
                        .setValue("allowedUsers"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Allowed Roles")
                        .setDescription("Roles that will be unaffected by the word filter")
                        .setValue("allowedRoles"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Allowed Channels")
                        .setDescription("Channels where the word filter will not apply")
                        .setValue("allowedChannels")
                )
                .setDisabled(!current.enabled)
        );

        const embed = new EmojiEmbed()
            .setTitle("Word Filters")
            .setDescription(
                `${emojiFromBoolean(current.enabled)} **Enabled**\n` +
                    `**Strict Words:** ${listToAndMore(current.words.strict, 5)}\n` +
                    `**Loose Words:** ${listToAndMore(current.words.loose, 5)}\n\n` +
                    `**Users:** ` +
                    listToAndMore(
                        current.allowed.users.map((user) => `<@${user}>`),
                        5
                    ) +
                    `\n` +
                    `**Roles:** ` +
                    listToAndMore(
                        current.allowed.roles.map((role) => `<@&${role}>`),
                        5
                    ) +
                    `\n` +
                    `**Channels:** ` +
                    listToAndMore(
                        current.allowed.channels.map((channel) => `<#${channel}>`),
                        5
                    )
            )
            .setStatus("Success")
            .setEmoji("GUILD.SETTINGS.GREEN");

        await interaction.editReply({ embeds: [embed], components: [selectMenu, buttons] });

        let i: ButtonInteraction | StringSelectMenuInteraction;
        try {
            i = (await m.awaitMessageComponent({
                filter: (i) => interaction.user.id === i.user.id && i.message.id === m.id,
                time: 300000
            })) as ButtonInteraction | StringSelectMenuInteraction;
        } catch (e) {
            closed = true;
            break;
        }

        if (i.isButton()) {
            await i.deferUpdate();
            switch (i.customId) {
                case "back": {
                    closed = true;
                    break;
                }
                case "enabled": {
                    current.enabled = !current.enabled;
                    break;
                }
            }
        } else {
            switch (i.values[0]) {
                case "words": {
                    await interaction.editReply({
                        embeds: [
                            new EmojiEmbed()
                                .setTitle("Word Filter")
                                .setDescription("Modal opened. If you can't see it, click back and try again.")
                                .setStatus("Success")
                                .setEmoji("GUILD.SETTINGS.GREEN")
                        ],
                        components: [
                            new ActionRowBuilder<ButtonBuilder>().addComponents(
                                new ButtonBuilder()
                                    .setLabel("Back")
                                    .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                                    .setStyle(ButtonStyle.Primary)
                                    .setCustomId("back")
                            )
                        ]
                    });
                    const modal = new ModalBuilder()
                        .setTitle("Word Filter")
                        .setCustomId("wordFilter")
                        .addComponents(
                            new ActionRowBuilder<TextInputBuilder>().addComponents(
                                new TextInputBuilder()
                                    .setCustomId("wordStrict")
                                    .setLabel("Strict Words")
                                    .setPlaceholder(
                                        "Matches anywhere in the message, including surrounded by other characters"
                                    )
                                    .setValue(current.words.strict.join(", "))
                                    .setStyle(TextInputStyle.Paragraph)
                                    .setRequired(false)
                            ),
                            new ActionRowBuilder<TextInputBuilder>().addComponents(
                                new TextInputBuilder()
                                    .setCustomId("wordLoose")
                                    .setLabel("Loose Words")
                                    .setPlaceholder(
                                        "Matches only if the word is by itself, surrounded by spaces or punctuation"
                                    )
                                    .setValue(current.words.loose.join(", "))
                                    .setStyle(TextInputStyle.Paragraph)
                                    .setRequired(false)
                            )
                        );

                    await i.showModal(modal);
                    let out;
                    try {
                        out = await modalInteractionCollector(m, interaction.user);
                    } catch (e) {
                        break;
                    }
                    if (!out) break;
                    if (out.isButton()) break;
                    current.words.strict = out.fields
                        .getTextInputValue("wordStrict")
                        .split(",")
                        .map((s) => s.trim())
                        .filter((s) => s.length > 0);
                    current.words.loose = out.fields
                        .getTextInputValue("wordLoose")
                        .split(",")
                        .map((s) => s.trim())
                        .filter((s) => s.length > 0);
                    break;
                }
                case "allowedUsers": {
                    await i.deferUpdate();
                    current.allowed.users = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.users,
                        "member",
                        "Word Filter"
                    );
                    break;
                }
                case "allowedRoles": {
                    await i.deferUpdate();
                    current.allowed.roles = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.roles,
                        "role",
                        "Word Filter"
                    );
                    break;
                }
                case "allowedChannels": {
                    await i.deferUpdate();
                    current.allowed.channels = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.channels,
                        "channel",
                        "Word Filter"
                    );
                    break;
                }
            }
        }
    } while (!closed);
    return current;
};

const inviteMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    current: {
        enabled: boolean;
        allowed: { users: string[]; roles: string[]; channels: string[] };
    }
): Promise<{
    enabled: boolean;
    allowed: { users: string[]; roles: string[]; channels: string[] };
}> => {
    let closed = false;
    do {
        const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId("back")
                .setLabel("Back")
                .setStyle(ButtonStyle.Secondary)
                .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("enabled")
                .setLabel(current.enabled ? "Enabled" : "Disabled")
                .setStyle(current.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
                .setEmoji(emojiFromBoolean(current.enabled, "id") as APIMessageComponentEmoji)
        );
        const menu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("toEdit")
                .setPlaceholder("Edit your allow list")
                .addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Users")
                        .setDescription("Users that are allowed to send invites")
                        .setValue("users"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Roles")
                        .setDescription("Roles that are allowed to send invites")
                        .setValue("roles"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Channels")
                        .setDescription("Channels that anyone is allowed to send invites in")
                        .setValue("channels")
                )
                .setDisabled(!current.enabled)
        );

        const embed = new EmojiEmbed()
            .setTitle("Invite Settings")
            .setDescription(
                "Automatically deletes invites sent by users (outside of staff members and self promotion channels)" +
                    `\n\n` +
                    `${emojiFromBoolean(current.enabled)} **${current.enabled ? "Enabled" : "Disabled"}**\n\n` +
                    `**Users:** ` +
                    listToAndMore(
                        current.allowed.users.map((user) => `<@${user}>`),
                        5
                    ) +
                    `\n` +
                    `**Roles:** ` +
                    listToAndMore(
                        current.allowed.roles.map((role) => `<@&${role}>`),
                        5
                    ) +
                    `\n` +
                    `**Channels:** ` +
                    listToAndMore(
                        current.allowed.channels.map((channel) => `<#${channel}>`),
                        5
                    )
            )
            .setStatus("Success")
            .setEmoji("GUILD.SETTINGS.GREEN");

        await interaction.editReply({ embeds: [embed], components: [menu, buttons] });

        let i: ButtonInteraction | StringSelectMenuInteraction;
        try {
            i = (await m.awaitMessageComponent({
                filter: (i) => interaction.user.id === i.user.id && i.message.id === m.id,
                time: 300000
            })) as ButtonInteraction | StringSelectMenuInteraction;
        } catch (e) {
            return current;
        }

        if (i.isButton()) {
            await i.deferUpdate();
            switch (i.customId) {
                case "back": {
                    closed = true;
                    break;
                }
                case "enabled": {
                    current.enabled = !current.enabled;
                    break;
                }
            }
        } else {
            await i.deferUpdate();
            switch (i.values[0]) {
                case "users": {
                    current.allowed.users = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.users,
                        "member",
                        "Invite Settings"
                    );
                    break;
                }
                case "roles": {
                    current.allowed.roles = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.roles,
                        "role",
                        "Invite Settings"
                    );
                    break;
                }
                case "channels": {
                    current.allowed.channels = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.channels,
                        "channel",
                        "Invite Settings"
                    );
                    break;
                }
            }
        }
    } while (!closed);
    return current;
};

const mentionMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    current: {
        mass: number;
        everyone: boolean;
        roles: boolean;
        allowed: {
            roles: string[];
            rolesToMention: string[];
            users: string[];
            channels: string[];
        };
    }
): Promise<{
    mass: number;
    everyone: boolean;
    roles: boolean;
    allowed: {
        roles: string[];
        rolesToMention: string[];
        users: string[];
        channels: string[];
    };
}> => {
    let closed = false;

    do {
        const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId("back")
                .setLabel("Back")
                .setStyle(ButtonStyle.Secondary)
                .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("everyone")
                .setLabel(current.everyone ? "Everyone" : "No one")
                .setStyle(current.everyone ? ButtonStyle.Success : ButtonStyle.Danger)
                .setEmoji(emojiFromBoolean(current.everyone, "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("roles")
                .setLabel(current.roles ? "Roles" : "No roles")
                .setStyle(current.roles ? ButtonStyle.Success : ButtonStyle.Danger)
                .setEmoji(emojiFromBoolean(current.roles, "id") as APIMessageComponentEmoji)
        );
        const menu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("toEdit")
                .setPlaceholder("Edit mention settings")
                .addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Mass Mention Amount")
                        .setDescription("The amount of mentions before the bot will delete the message")
                        .setValue("mass"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Roles")
                        .setDescription("Roles that are able to be mentioned")
                        .setValue("roles")
                )
        );

        const allowedMenu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("allowed")
                .setPlaceholder("Edit allowed list")
                .addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Users")
                        .setDescription("Users that are unaffected by the mention filter")
                        .setValue("users"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Roles")
                        .setDescription("Roles that are unaffected by the mention filter")
                        .setValue("roles"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Channels")
                        .setDescription("Channels where anyone is unaffected by the mention filter")
                        .setValue("channels")
                )
        );

        const embed = new EmojiEmbed()
            .setTitle("Mention Settings")
            .setDescription(
                `Log when members mention:\n` +
                    `${emojiFromBoolean(true)} **${current.mass}+ members** in one message\n` +
                    `${emojiFromBoolean(current.everyone)} **Everyone**\n` +
                    `${emojiFromBoolean(current.roles)} **Roles**\n` +
                    (current.allowed.rolesToMention.length > 0
                        ? `> *Except for ${listToAndMore(
                                current.allowed.rolesToMention.map((r) => `<@&${r}>`),
                                3
                            )}*\n`
                        : "") +
                    "\n" +
                    `Except if...\n` +
                    (current.allowed.users.length > 0
                        ? `> Member is: ${listToAndMore(
                                current.allowed.users.map((u) => `<@${u}>`),
                                3
                            )}\n`
                        : "") +
                    (current.allowed.roles.length > 0
                        ? `> Member has role: ${listToAndMore(
                                current.allowed.roles.map((r) => `<@&${r}>`),
                                3
                            )}\n`
                        : "") +
                    (current.allowed.channels.length > 0
                        ? `> In channel: ${listToAndMore(
                                current.allowed.channels.map((c) => `<#${c}>`),
                                3
                            )}\n`
                        : "") +
                    (current.allowed.users.length == 0 || current.allowed.roles.length == 0 || current.allowed.channels.length == 0 ?
                        "> *No exceptions*\n" : ""
                    )
            )
            .setStatus("Success")
            .setEmoji("GUILD.SETTINGS.GREEN");

        await interaction.editReply({ embeds: [embed], components: [menu, allowedMenu, buttons] });

        let i: ButtonInteraction | StringSelectMenuInteraction;
        try {
            i = (await m.awaitMessageComponent({
                filter: (i) => interaction.user.id === i.user.id && i.message.id === m.id,
                time: 300000
            })) as ButtonInteraction | StringSelectMenuInteraction;
        } catch (e) {
            closed = true;
            break;
        }

        if (i.isButton()) {
            await i.deferUpdate();
            switch (i.customId) {
                case "back": {
                    closed = true;
                    break;
                }
                case "everyone": {
                    current.everyone = !current.everyone;
                    break;
                }
                case "roles": {
                    current.roles = !current.roles;
                    break;
                }
            }
        } else {
            switch (i.customId) {
                case "toEdit": {
                    switch (i.values[0]) {
                        case "mass": {
                            await interaction.editReply({
                                embeds: [
                                    new EmojiEmbed()
                                        .setTitle("Word Filter")
                                        .setDescription("Modal opened. If you can't see it, click back and try again.")
                                        .setStatus("Success")
                                        .setEmoji("GUILD.SETTINGS.GREEN")
                                ],
                                components: [
                                    new ActionRowBuilder<ButtonBuilder>().addComponents(
                                        new ButtonBuilder()
                                            .setLabel("Back")
                                            .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                                            .setStyle(ButtonStyle.Primary)
                                            .setCustomId("back")
                                    )
                                ]
                            });
                            const modal = new ModalBuilder()
                                .setTitle("Mass Mention Amount")
                                .setCustomId("mass")
                                .addComponents(
                                    new ActionRowBuilder<TextInputBuilder>().addComponents(
                                        new TextInputBuilder()
                                            .setCustomId("mass")
                                            .setPlaceholder("Amount")
                                            .setMinLength(1)
                                            .setMaxLength(3)
                                            .setStyle(TextInputStyle.Short)
                                    )
                                );
                            await i.showModal(modal);
                            let out;
                            try {
                                out = await modalInteractionCollector(m, interaction.user);
                            } catch (e) {
                                break;
                            }
                            if (!out) break;
                            if (out.isButton()) break;
                            current.mass = parseInt(out.fields.getTextInputValue("mass"));
                            break;
                        }
                        case "roles": {
                            await i.deferUpdate();
                            current.allowed.rolesToMention = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.rolesToMention,
                                "role",
                                "Mention Settings"
                            );
                            break;
                        }
                    }
                    break;
                }
                case "allowed": {
                    await i.deferUpdate();
                    switch (i.values[0]) {
                        case "users": {
                            current.allowed.users = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.users,
                                "member",
                                "Mention Settings"
                            );
                            break;
                        }
                        case "roles": {
                            current.allowed.roles = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.roles,
                                "role",
                                "Mention Settings"
                            );
                            break;
                        }
                        case "channels": {
                            current.allowed.channels = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.channels,
                                "channel",
                                "Mention Settings"
                            );
                            break;
                        }
                    }
                    break;
                }
            }
        }
    } while (!closed);
    return current;
};

const cleanMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    current?: {
        channels?: string[];
        allowed?: {
            roles: string[];
            users: string[];
        };
    }
): Promise<{
    channels: string[];
    allowed: {
        roles: string[];
        users: string[];
    };
}> => {
    let closed = false;
    if (!current) current = { channels: [], allowed: { roles: [], users: [] } };
    if (!current.channels) current.channels = [];
    if (!current.allowed) current.allowed = { roles: [], users: [] };

    const channelMenu = new ActionRowBuilder<ChannelSelectMenuBuilder>().addComponents(
        new ChannelSelectMenuBuilder().setCustomId("toAdd").setPlaceholder("Select a channel")
    );

    const allowedMenu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
        new StringSelectMenuBuilder()
            .setCustomId("allowed")
            .setPlaceholder("Edit exceptions")
            .addOptions(
                new StringSelectMenuOptionBuilder()
                    .setLabel("Users")
                    .setDescription("Users that are unaffected by the mention filter")
                    .setValue("users"),
                new StringSelectMenuOptionBuilder()
                    .setLabel("Roles")
                    .setDescription("Roles that are unaffected by the mention filter")
                    .setValue("roles")
            )
    );

    do {
        const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId("back")
                .setLabel("Back")
                .setStyle(ButtonStyle.Primary)
                .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
        );

        const embed = new EmojiEmbed()
            .setTitle("Clean Settings")
            .setEmoji("GUILD.SETTINGS.GREEN")
            .setDescription(
                `Current clean channels:\n\n` +
                    `${
                        current.channels.length > 0
                            ? listToAndMore(
                                  current.channels.map((c) => `<#${c}>`),
                                  10
                              )
                            : "None"
                    }\n\n`
            )
            .setStatus("Success");

        await interaction.editReply({ embeds: [embed], components: [channelMenu, allowedMenu, buttons] });

        let i: ButtonInteraction | ChannelSelectMenuInteraction;
        try {
            i = (await m.awaitMessageComponent({
                filter: (i) => interaction.user.id === i.user.id && i.message.id === m.id,
                time: 300000
            })) as ButtonInteraction | ChannelSelectMenuInteraction;
        } catch (e) {
            closed = true;
            break;
        }
        await i.deferUpdate();
        if (i.isButton()) {
            switch (i.customId) {
                case "back": {
                    closed = true;
                    break;
                }
            }
        } else {
            switch (i.customId) {
                case "toAdd": {
                    const channelEmbed = new EmojiEmbed()
                        .setTitle("Clean Settings")
                        .setDescription(`Editing <#${i.values[0]}>`)
                        .setEmoji("GUILD.SETTINGS.GREEN")
                        .setStatus("Success");
                    const channelButtons = new ActionRowBuilder<ButtonBuilder>().addComponents(
                        new ButtonBuilder()
                            .setCustomId("back")
                            .setLabel("Back")
                            .setStyle(ButtonStyle.Primary)
                            .setEmoji(getEmojiByName("CONTROL.LEFT", "id")),
                        new ButtonBuilder()
                            .setCustomId("switch")
                            .setLabel(current.channels.includes(i.values[0]!) ? "Remove" : "Add")
                            .setStyle(
                                current.channels.includes(i.values[0]!) ? ButtonStyle.Danger : ButtonStyle.Success
                            )
                    );

                    await i.editReply({ embeds: [channelEmbed], components: [channelButtons] });
                    let j: ButtonInteraction;
                    try {
                        j = (await m.awaitMessageComponent({
                            filter: (i) => interaction.user.id === i.user.id && i.message.id === m.id,
                            time: 300000
                        })) as ButtonInteraction;
                    } catch (e) {
                        closed = true;
                        break;
                    }
                    await j.deferUpdate();
                    switch (j.customId) {
                        case "back": {
                            break;
                        }
                        case "switch": {
                            if (current.channels.includes(i.values[0]!)) {
                                current.channels.splice(current.channels.indexOf(i.values[0]!), 1);
                            } else {
                                current.channels.push(i.values[0]!);
                            }
                        }
                    }
                    break;
                }
                case "allowed": {
                    switch (i.values[0]) {
                        case "users": {
                            current.allowed.users = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.users,
                                "member",
                                "Mention Settings"
                            );
                            break;
                        }
                        case "roles": {
                            current.allowed.roles = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.roles,
                                "role",
                                "Mention Settings"
                            );
                            break;
                        }
                    }
                    break;
                }
            }
        }
    } while (!closed);

    return current as {
        channels: string[];
        allowed: {
            roles: string[];
            users: string[];
        };
    };
};

const callback = async (interaction: CommandInteraction): Promise<void> => {
    if (!interaction.guild) return;
    const m = await interaction.reply({ embeds: LoadingEmbed, fetchReply: true, ephemeral: true });
    const config = (await client.database.guilds.read(interaction.guild.id)).filters;

    let closed = false;

    const button = new ActionRowBuilder<ButtonBuilder>().addComponents(
        new ButtonBuilder().setCustomId("save").setLabel("Save").setStyle(ButtonStyle.Success)
    );

    do {
        const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("filter")
                .setPlaceholder("Select a filter to edit")
                .addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Invites")
                        .setDescription("Automatically delete messages containing server invites")
                        .setValue("invites"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Mentions")
                        .setDescription("Deletes messages with excessive mentions")
                        .setValue("mentions"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Words")
                        .setDescription("Delete messages containing filtered words")
                        .setValue("words"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Malware")
                        .setDescription("Automatically delete files and links containing malware")
                        .setValue("malware"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Images")
                        .setDescription("Checks performed on images (NSFW, size checking, etc.)")
                        .setValue("images"),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Clean")
                        .setDescription("Automatically delete new messages in specific channels")
                        .setValue("clean")
                )
        );

        const embed = new EmojiEmbed()
            .setTitle("Automod Settings")
            .setDescription(
                `${emojiFromBoolean(config.invite.enabled)} **Invites**\n` +
                    `${emojiFromBoolean(
                        config.pings.everyone || config.pings.mass > 0 || config.pings.roles
                    )} **Mentions**\n` +
                    `${emojiFromBoolean(config.wordFilter.enabled)} **Words**\n` +
                    `${emojiFromBoolean(config.malware)} **Malware**\n` +
                    `${emojiFromBoolean(config.images.NSFW || config.images.size)} **Images**\n` +
                    `${emojiFromBoolean(config.clean.channels.length > 0)} **Clean**\n`
            )
            .setStatus("Success")
            .setEmoji("GUILD.SETTINGS.GREEN");

        await interaction.editReply({ embeds: [embed], components: [selectMenu, button] });

        let i: StringSelectMenuInteraction | ButtonInteraction;
        try {
            i = (await m.awaitMessageComponent({
                filter: (i) => i.user.id === interaction.user.id && i.message.id === m.id,
                time: 300000
            })) as StringSelectMenuInteraction | ButtonInteraction;
        } catch (e) {
            closed = true;
            continue;
        }
        if (i.isButton()) {
            await i.deferUpdate();
            await client.database.guilds.write(interaction.guild.id, { filters: config });
            await client.memory.forceUpdate(interaction.guild.id);
        } else {
            switch (i.values[0]) {
                case "invites": {
                    i.deferUpdate();
                    config.invite = await inviteMenu(i, m, config.invite);
                    break;
                }
                case "mentions": {
                    i.deferUpdate();
                    config.pings = await mentionMenu(i, m, config.pings);
                    break;
                }
                case "words": {
                    config.wordFilter = await wordMenu(i, m, config.wordFilter);
                    break;
                }
                case "malware": {
                    i.deferUpdate();
                    config.malware = !config.malware;
                    break;
                }
                case "images": {
                    i.deferUpdate();
                    const next = await imageMenu(i, m, config.images);
                    config.images = next;
                    break;
                }
                case "clean": {
                    i.deferUpdate();
                    const next = await cleanMenu(i, m, config.clean);
                    config.clean = next;
                    break;
                }
            }
        }
    } while (!closed);
    await interaction.deleteReply();
};

const check = (interaction: CommandInteraction, _partial: boolean = false) => {
    const member = interaction.member as Discord.GuildMember;
    if (!member.permissions.has("ManageMessages"))
        return "You must have the *Manage Messages* permission to use this command";
    return true;
};

export { command };
export { callback };
export { check };
