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 = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.users,
                        "member",
                        "Word Filter"
                    );
                    unsavedChanges = true;
                    break;
                }
                case "allowedRoles": {
                    await i.deferUpdate();
                    current.allowed.roles = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.roles,
                        "role",
                        "Word Filter"
                    );
                    unsavedChanges = true;
                    break;
                }
                case "allowedChannels": {
                    await i.deferUpdate();
                    current.allowed.channels = 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 = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.users,
                        "member",
                        "Invite Settings"
                    );
                    unsavedChanges = true;
                    break;
                }
                case "roles": {
                    current.allowed.roles = await toSelectMenu(
                        interaction,
                        m,
                        current.allowed.roles,
                        "role",
                        "Invite Settings"
                    );
                    unsavedChanges = true;
                    break;
                }
                case "channels": {
                    current.allowed.channels = 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
                        ? "> *No exceptions*\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 = 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 = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.users,
                                "member",
                                "Mention Settings"
                            );
                            unsavedChanges = true;
                            break;
                        }
                        case "roles": {
                            current.allowed.roles = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.roles,
                                "role",
                                "Mention Settings"
                            );
                            unsavedChanges = true;
                            break;
                        }
                        case "channels": {
                            current.allowed.channels = 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 = await toSelectMenu(
                                interaction,
                                m,
                                current.allowed.users,
                                "member",
                                "Mention Settings"
                            );
                            unsavedChanges = true;
                            break;
                        }
                        case "roles": {
                            current.allowed.roles = 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": {
                    config.invite = await inviteMenu(i, m, _.isEqual(config, current), config.invite);
                    break;
                }
                case "mentions": {
                    config.pings = await mentionMenu(i, m, _.isEqual(config, current), config.pings);
                    break;
                }
                case "words": {
                    config.wordFilter = await wordMenu(i, m, _.isEqual(config, current), config.wordFilter);
                    break;
                }
                case "malware": {
                    config.malware = !config.malware;
                    break;
                }
                case "images": {
                    const next = await imageMenu(i, m, _.isEqual(config, current), config.images);
                    config.images = next;
                    break;
                }
                case "clean": {
                    const next = await cleanMenu(i, m, _.isEqual(config, current), 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 };
