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