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";
import _ from "lodash";

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,
    unsavedChanges: boolean,
    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`
            )
            .setFooter({
                text: unsavedChanges ? "No changes made" : "Changes not saved"
            });

        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;
                unsavedChanges = true;
                break;
            }
            case "size": {
                current.size = !current.size;
                unsavedChanges = true;
                break;
            }
        }
    } while (!closed);
    return current;
};

const wordMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    unsavedChanges: boolean,
    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")
            .setFooter({
                text: unsavedChanges ? "No changes made" : "Changes not saved"
            });

        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;
                    unsavedChanges = true;
                    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);
                    unsavedChanges = true;
                    break;
                }
                case "allowedUsers": {
                    await i.deferUpdate();
                    current.allowed.users = _.cloneDeep(
                        await toSelectMenu(interaction, m, current.allowed.users, "member", "Word Filter")
                    );
                    unsavedChanges = true;
                    break;
                }
                case "allowedRoles": {
                    await i.deferUpdate();
                    current.allowed.roles = _.cloneDeep(
                        await toSelectMenu(interaction, m, current.allowed.roles, "role", "Word Filter")
                    );
                    unsavedChanges = true;
                    break;
                }
                case "allowedChannels": {
                    await i.deferUpdate();
                    current.allowed.channels = _.cloneDeep(
                        await toSelectMenu(interaction, m, current.allowed.channels, "channel", "Word Filter")
                    );
                    unsavedChanges = true;
                    break;
                }
            }
        }
    } while (!closed);
    return current;
};

const inviteMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    unsavedChanges: boolean,
    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")
            .setFooter({
                text: unsavedChanges ? "No changes made" : "Changes not saved"
            });

        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;
                    unsavedChanges = true;
                    break;
                }
            }
        } else {
            await i.deferUpdate();
            switch (i.values[0]) {
                case "users": {
                    current.allowed.users = _.cloneDeep(
                        await toSelectMenu(interaction, m, current.allowed.users, "member", "Invite Settings")
                    );
                    unsavedChanges = true;
                    break;
                }
                case "roles": {
                    current.allowed.roles = _.cloneDeep(
                        await toSelectMenu(interaction, m, current.allowed.roles, "role", "Invite Settings")
                    );
                    unsavedChanges = true;
                    break;
                }
                case "channels": {
                    current.allowed.channels = _.cloneDeep(
                        await toSelectMenu(interaction, m, current.allowed.channels, "channel", "Invite Settings")
                    );
                    unsavedChanges = true;
                    break;
                }
            }
        }
    } while (!closed);
    return current;
};

const mentionMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    unsavedChanges: boolean,
    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
                        ? "> *Nobody on allowed lists*\n"
                        : "")
            )
            .setStatus("Success")
            .setEmoji("GUILD.SETTINGS.GREEN")
            .setFooter({
                text: unsavedChanges ? "No changes made" : "Changes not saved"
            });

        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;
                    unsavedChanges = true;
                    break;
                }
                case "roles": {
                    current.roles = !current.roles;
                    unsavedChanges = true;
                    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"));
                            unsavedChanges = true;
                            break;
                        }
                        case "roles": {
                            await i.deferUpdate();
                            current.allowed.rolesToMention = _.cloneDeep(
                                await toSelectMenu(
                                    interaction,
                                    m,
                                    current.allowed.rolesToMention,
                                    "role",
                                    "Mention Settings"
                                )
                            );
                            unsavedChanges = true;
                            break;
                        }
                    }
                    break;
                }
                case "allowed": {
                    await i.deferUpdate();
                    switch (i.values[0]) {
                        case "users": {
                            current.allowed.users = _.cloneDeep(
                                await toSelectMenu(interaction, m, current.allowed.users, "member", "Mention Settings")
                            );
                            unsavedChanges = true;
                            break;
                        }
                        case "roles": {
                            current.allowed.roles = _.cloneDeep(
                                await toSelectMenu(interaction, m, current.allowed.roles, "role", "Mention Settings")
                            );
                            unsavedChanges = true;
                            break;
                        }
                        case "channels": {
                            current.allowed.channels = _.cloneDeep(
                                await toSelectMenu(
                                    interaction,
                                    m,
                                    current.allowed.channels,
                                    "channel",
                                    "Mention Settings"
                                )
                            );
                            unsavedChanges = true;
                            break;
                        }
                    }
                    break;
                }
            }
        }
    } while (!closed);
    return current;
};

const cleanMenu = async (
    interaction: StringSelectMenuInteraction,
    m: Message,
    unsavedChanges: boolean,
    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")
            .setFooter({
                text: unsavedChanges ? "No changes made" : "Changes not saved"
            });

        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]!);
                            }
                        }
                    }
                    unsavedChanges = true;
                    break;
                }
                case "allowed": {
                    switch (i.values[0]) {
                        case "users": {
                            current.allowed.users = _.cloneDeep(
                                await toSelectMenu(interaction, m, current.allowed.users, "member", "Mention Settings")
                            );
                            unsavedChanges = true;
                            break;
                        }
                        case "roles": {
                            current.allowed.roles = _.cloneDeep(
                                await toSelectMenu(interaction, m, current.allowed.roles, "role", "Mention Settings")
                            );
                            unsavedChanges = true;
                            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 });
    let config = (await client.database.guilds.read(interaction.guild.id)).filters;

    let closed = false;

    let current = _.cloneDeep(config);
    do {
        const button = new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId("save")
                .setLabel("Save")
                .setStyle(ButtonStyle.Success)
                .setDisabled(_.isEqual(config, current))
        );
        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")
            .setFooter({
                text: _.isEqual(config, current) ? "No changes made" : "Changes not saved"
            });

        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;
        }
        await i.deferUpdate();
        if (i.isButton()) {
            await client.database.guilds.write(interaction.guild.id, { filters: current });
            await client.memory.forceUpdate(interaction.guild.id);
            config = current;
            current = _.cloneDeep(config);
        } else {
            switch (i.values[0]) {
                case "invites": {
                    current.invite = await inviteMenu(i, m, _.isEqual(config, current), current.invite);
                    break;
                }
                case "mentions": {
                    current.pings = await mentionMenu(i, m, _.isEqual(config, current), current.pings);
                    break;
                }
                case "words": {
                    current.wordFilter = await wordMenu(i, m, _.isEqual(config, current), current.wordFilter);
                    break;
                }
                case "malware": {
                    current.malware = !current.malware;
                    break;
                }
                case "images": {
                    const next = await imageMenu(i, m, _.isEqual(config, current), current.images);
                    current.images = next;
                    break;
                }
                case "clean": {
                    const next = await cleanMenu(i, m, _.isEqual(config, current), config.clean);
                    current.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 };
