import type Discord from "discord.js";
import { ActionRowBuilder, AnyComponent, AnyComponentBuilder, AnySelectMenuInteraction, APIMessageComponentEmoji, ButtonBuilder, ButtonInteraction, ButtonStyle, ChannelSelectMenuBuilder, ChannelSelectMenuInteraction, CommandInteraction, Guild, GuildMember, GuildTextBasedChannel, MentionableSelectMenuBuilder, Message, Role, RoleSelectMenuBuilder, RoleSelectMenuInteraction, SelectMenuBuilder, StringSelectMenuBuilder, StringSelectMenuInteraction, StringSelectMenuOptionBuilder, 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";


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 listToAndMore = (list: string[], max: number) => {
    // PineappleFan, Coded, Mini (and 10 more)
    if(list.length > max) {
        return list.slice(0, max).join(", ") + ` (and ${list.length - max} more)`;
    }
    return list.join(", ");
}

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 Channel" }));
                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");
        let 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 interaction.channel!.awaitMessageComponent({filter: i => i.user.id === interaction.user.id, time: 300000});
        } catch(e) {
            closed = true;
            break;
        }

        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 {
        closed = true;
    } 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: [buttons, menu]});

        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 {
        closed = true;
    } while(!closed);
    return current
}

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")
                    )
            );

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

    } while(!closed)

};

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 };
