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")
            .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 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"),
                    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`
                            : ""
                    }`
            )
            .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": {
                    await i.deferUpdate();
                    config.malware = !config.malware;
                    break;
                }
                case "images": {
                    await i.deferUpdate();
                    const next = await imageMenu(i, m, config.images);
                    config.images = next;
                    break;
                }
                case "clean": {
                    await 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 };
