import type Discord from "discord.js";
import {
    ActionRowBuilder,
    APIMessageComponentEmoji,
    ButtonBuilder,
    ButtonInteraction,
    ButtonStyle,
    CommandInteraction,
    Message,
    ModalBuilder,
    RoleSelectMenuBuilder,
    RoleSelectMenuInteraction,
    StringSelectMenuBuilder,
    StringSelectMenuInteraction,
    StringSelectMenuOptionBuilder,
    TextInputBuilder,
    TextInputStyle
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import { LoadingEmbed } from "../../utils/defaults.js";
import client from "../../utils/client.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import createPageIndicator from "../../utils/createPageIndicator.js";
import { configToDropdown } from "../../actions/roleMenu.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
import ellipsis from "../../utils/ellipsis.js";
import _ from "lodash";

const cross = getEmojiByName("CONTROL.CROSS");
const tick = getEmojiByName("CONTROL.TICK");
const isEqual = _.isEqual;

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder.setName("rolemenu").setDescription("Allows you to change settings for the servers rolemenu");

interface ObjectSchema {
    enabled?: boolean;
    name: string;
    description?: string;
    min: number;
    max: number;
    options: {
        name: string;
        description: string | null;
        role: string;
    }[];
}

const defaultRolePageConfig = {
    name: "Role Menu Page",
    description: "A new role menu page",
    min: 0,
    max: 0,
    options: [{ name: "Role 1", description: null, role: "No role set" }]
};

const reorderRoleMenuPages = async (interaction: CommandInteraction, m: Message, currentObj: ObjectSchema[]) => {
    const reorderRow = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
        new StringSelectMenuBuilder()
            .setCustomId("reorder")
            .setPlaceholder("Select all pages in the order you want them to appear.")
            .setMinValues(currentObj.length)
            .setMaxValues(currentObj.length)
            .addOptions(
                currentObj.map((o, i) => new StringSelectMenuOptionBuilder().setLabel(o.name).setValue(i.toString()))
            )
    );
    const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
        new ButtonBuilder()
            .setCustomId("back")
            .setLabel("Back")
            .setStyle(ButtonStyle.Secondary)
            .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji)
    );
    await interaction.editReply({
        embeds: [
            new EmojiEmbed()
                .setTitle("Role Menu")
                .setDescription("Select pages in the order you want them to appear.")
                .setStatus("Success")
        ],
        components: [reorderRow, buttonRow]
    });
    let out: StringSelectMenuInteraction | ButtonInteraction | null;
    try {
        out = (await m.awaitMessageComponent({
            filter: (i) => i.channel!.id === interaction.channel!.id,
            time: 300000
        })) as StringSelectMenuInteraction | ButtonInteraction | null;
    } catch (e) {
        console.error(e);
        out = null;
    }
    if (!out) return;
    await out.deferUpdate();
    if (out.isButton()) return;
    const values = out.values;

    const newOrder: ObjectSchema[] = currentObj.map((_, i) => {
        const index = values.findIndex((v) => v === i.toString());
        return currentObj[index];
    }) as ObjectSchema[];

    return newOrder;
};

const editNameDescription = async (
    i: ButtonInteraction,
    interaction: StringSelectMenuInteraction | ButtonInteraction,
    m: Message,
    data: { name?: string; description?: string; bounds?: { min: number; max: number } },
    addBounds: boolean = false
): Promise<[string | undefined, string | undefined, { min: number; max: number } | undefined]> => {
    let { name, description, bounds } = data;
    const components = [
        new ActionRowBuilder<TextInputBuilder>().addComponents(
            new TextInputBuilder()
                .setLabel("Name")
                .setCustomId("name")
                .setPlaceholder("The name of the role (e.g. Programmer)")
                .setStyle(TextInputStyle.Short)
                .setValue(name ?? "")
                .setRequired(true)
                .setMaxLength(100)
        ),
        new ActionRowBuilder<TextInputBuilder>().addComponents(
            new TextInputBuilder()
                .setLabel("Description")
                .setCustomId("description")
                .setPlaceholder("A short description of the role (e.g. A role for people who code)")
                .setStyle(TextInputStyle.Short)
                .setValue(description ?? "")
                .setRequired(false)
                .setMaxLength(100)
        )
    ];
    if (addBounds && bounds) {
        components.push(
            new ActionRowBuilder<TextInputBuilder>().addComponents(
                new TextInputBuilder()
                    .setLabel("Minimum")
                    .setCustomId("min")
                    .setPlaceholder("The minimum number of roles a user can select")
                    .setStyle(TextInputStyle.Short)
                    .setValue(bounds.min.toString())
                    .setRequired(true)
                    .setMaxLength(2)
            ),
            new ActionRowBuilder<TextInputBuilder>().addComponents(
                new TextInputBuilder()
                    .setLabel("Maximum")
                    .setCustomId("max")
                    .setPlaceholder("The maximum number of roles a user can select (0 for no limit)")
                    .setStyle(TextInputStyle.Short)
                    .setValue(bounds.max.toString())
                    .setRequired(true)
                    .setMaxLength(2)
            )
        );
    }
    const modal = new ModalBuilder()
        .setTitle("Edit Name and Description")
        .setCustomId("editNameDescription")
        .addComponents(...components);
    const button = new ActionRowBuilder<ButtonBuilder>().addComponents(
        new ButtonBuilder()
            .setCustomId("back")
            .setLabel("Back")
            .setStyle(ButtonStyle.Secondary)
            .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji)
    );

    await i.showModal(modal);
    await interaction.editReply({
        embeds: [
            new EmojiEmbed()
                .setTitle("Role Menu")
                .setDescription("Modal opened. If you can't see it, click back and try again.")
                .setStatus("Success")
        ],
        components: [button]
    });

    let out: Discord.ModalSubmitInteraction | null;
    try {
        out = (await modalInteractionCollector(m, interaction.user)) as Discord.ModalSubmitInteraction | null;
    } catch (e) {
        console.error(e);
        out = null;
    }
    if (!out) return [name, description, bounds];
    if (out.isButton()) return [name, description, bounds];
    name = out.fields.fields.find((f) => f.customId === "name")?.value ?? name;
    description = out.fields.fields.find((f) => f.customId === "description")?.value;
    if (addBounds) {
        const min = parseInt(out.fields.fields.find((f) => f.customId === "min")?.value!);
        const max = parseInt(out.fields.fields.find((f) => f.customId === "max")?.value!);
        bounds = { min, max };
    }
    return [name, description, bounds];
};

const defaultRoleMenuData = {
    enabled: true,
    name: "New Page",
    description: "",
    min: 0,
    max: 1,
    options: []
};

const editRoleMenuPage = async (
    interaction: StringSelectMenuInteraction | ButtonInteraction,
    m: Message,
    data?: ObjectSchema
): Promise<ObjectSchema | null> => {
    if (!data) data = _.cloneDeep(defaultRoleMenuData);
    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("edit")
            .setLabel("Edit")
            .setStyle(ButtonStyle.Primary)
            .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
        new ButtonBuilder()
            .setCustomId("addRole")
            .setLabel("Add Role")
            .setStyle(ButtonStyle.Secondary)
            .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id") as APIMessageComponentEmoji)
    );

    let back = false;
    do {
        const noRoles = data.options.length === 0;
        const previewSelect = configToDropdown(
            "Edit Roles",
            data.description
                ? {
                      name: data.name,
                      description: data.description,
                      min: 1,
                      max: 1,
                      options: noRoles ? [{ name: "Role 1", description: null, role: "No role set" }] : data.options
                  }
                : {
                      name: data.name,
                      min: 1,
                      max: 1,
                      options: noRoles ? [{ name: "Role 1", description: null, role: "No role set" }] : data.options
                  },
            undefined,
            noRoles
        );
        const embed = new EmojiEmbed()
            .setTitle(`${data.name}`)
            .setStatus("Success")
            .setDescription(
                `**Description:**\n> ${data.description ?? "*No description set*"}\n\n` +
                    `**Min:** ${data.min}` +
                    (data.min === 0 ? " (Members will be given a skip button)" : "") +
                    "\n" +
                    `**Max:** ${data.max}\n` +
                    `\n**Roles:** ${data.options.length === 0 ? "*No roles set*" : data.options.length}`
            );

        await interaction.editReply({ embeds: [embed], components: [previewSelect, buttons] });
        let i: StringSelectMenuInteraction | ButtonInteraction;
        try {
            i = (await m.awaitMessageComponent({
                time: 300000,
                filter: (i) =>
                    i.user.id === interaction.user.id && i.message.id === m.id && i.channelId === interaction.channelId
            })) as ButtonInteraction | StringSelectMenuInteraction;
        } catch (e) {
            back = true;
            break;
        }

        if (i.isStringSelectMenu()) {
            if (i.customId === "roles") {
                await i.deferUpdate();
                await createRoleMenuOptionPage(
                    interaction,
                    m,
                    data.options.find((o) => o.role === (i as StringSelectMenuInteraction).values[0]),
                    false
                );
            }
        } else if (i.isButton()) {
            switch (i.customId) {
                case "back": {
                    await i.deferUpdate();
                    back = true;
                    break;
                }
                case "edit": {
                    const [name, description, _bounds] = await editNameDescription(i, interaction, m, data);
                    data.name = name ? name : data.name;
                    description ? (data.description = description) : null;
                    break;
                }
                case "addRole": {
                    await i.deferUpdate();
                    const out = await createRoleMenuOptionPage(interaction, m, undefined, true);
                    if (out) data.options.push(out);
                    break;
                }
            }
        }
    } while (!back);
    if (isEqual(data, defaultRolePageConfig)) return null;
    return data;
};

const createRoleMenuOptionPage = async (
    interaction: StringSelectMenuInteraction | ButtonInteraction,
    m: Message,
    data?: { name: string; description: string | null; role: string },
    newRole: boolean = false
) => {
    const initialData = _.cloneDeep(data);
    const { renderRole } = client.logger;
    if (!data)
        data = {
            name: "New role Menu Option",
            description: null,
            role: ""
        };
    let back = false;
    const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
        new ButtonBuilder()
            .setCustomId("back")
            .setLabel(newRole ? "Add" : "Back")
            .setStyle(newRole ? ButtonStyle.Success : ButtonStyle.Secondary)
            .setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji),
        new ButtonBuilder()
            .setCustomId("edit")
            .setLabel("Edit Details")
            .setStyle(ButtonStyle.Primary)
            .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
        new ButtonBuilder()
            .setCustomId("delete")
            .setLabel("Delete")
            .setStyle(ButtonStyle.Danger)
            .setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji),
        new ButtonBuilder()
            .setCustomId("cancel")
            .setLabel("Cancel")
            .setStyle(ButtonStyle.Secondary)
            .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji)
    );
    do {
        const roleSelect = new RoleSelectMenuBuilder()
            .setCustomId("role")
            .setPlaceholder(data.role ? "Change role to" : "Select a role");
        const embed = new EmojiEmbed()
            .setTitle(`${data.name}`)
            .setStatus("Success")
            .setDescription(
                `**Description:**\n> ${data.description ?? "No description set"}\n\n` +
                    `**Role:** ${
                        data.role ? renderRole((await interaction.guild!.roles.fetch(data.role))!) : "No role set"
                    }\n`
            );

        await interaction.editReply({
            embeds: [embed],
            components: [new ActionRowBuilder<RoleSelectMenuBuilder>().addComponents(roleSelect), buttons]
        });

        let i: RoleSelectMenuInteraction | ButtonInteraction;
        try {
            i = (await m.awaitMessageComponent({
                time: 300000,
                filter: (i) =>
                    i.user.id === interaction.user.id && i.message.id === m.id && i.channelId === interaction.channelId
            })) as ButtonInteraction | RoleSelectMenuInteraction;
        } catch (e) {
            back = true;
            break;
        }

        if (i.isRoleSelectMenu()) {
            if (i.customId === "role") {
                await i.deferUpdate();
                data.role = (i as RoleSelectMenuInteraction).values[0]!;
                await interaction.editReply({
                    embeds: [
                        new EmojiEmbed().setTitle(`Applying changes`).setStatus("Danger").setEmoji("NUCLEUS.LOADING")
                    ],
                    components: []
                });
            }
        } else if (i.isButton()) {
            switch (i.customId) {
                case "back": {
                    await i.deferUpdate();
                    back = true;
                    break;
                }
                case "edit": {
                    const [name, description] = await editNameDescription(
                        i,
                        interaction,
                        m,
                        data as { name: string; description: string }
                    );
                    data.name = name ? name : data.name;
                    data.description = description ? description : data.description;
                    break;
                }
                case "delete": {
                    await i.deferUpdate();
                    return null;
                }
                case "cancel": {
                    await i.deferUpdate();
                    if (newRole) return null;
                    else return initialData;
                }
            }
        }
    } while (!back);
    return data;
};

const callback = async (interaction: CommandInteraction): Promise<void> => {
    if (!interaction.guild) return;
    const m = await interaction.reply({ embeds: LoadingEmbed, ephemeral: true, fetchReply: true });

    let page = 0;
    let closed = false;
    const config = await client.database.guilds.read(interaction.guild.id);
    const currentObject: typeof config.roleMenu = _.cloneDeep(config.roleMenu);
    let modified = false;
    do {
        const embed = new EmojiEmbed().setTitle("Role Menu").setEmoji("GUILD.GREEN").setStatus("Success");
        const noRoleMenus = currentObject.options.length === 0;
        let current: ObjectSchema;

        const pageSelect = new StringSelectMenuBuilder()
            .setCustomId("page")
            .setPlaceholder("Select a Role Menu page to manage");
        let actionSelect;
        if (page === 0) {
            actionSelect = new ActionRowBuilder<ButtonBuilder>().addComponents(
                new ButtonBuilder()
                    .setCustomId("switch")
                    .setLabel(currentObject.enabled ? "Enabled" : "Disabled")
                    .setStyle(currentObject.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
                    .setEmoji(
                        getEmojiByName(
                            currentObject.enabled ? "CONTROL.TICK" : "CONTROL.CROSS",
                            "id"
                        ) as APIMessageComponentEmoji
                    )
            );
        } else {
            actionSelect = new StringSelectMenuBuilder()
                .setCustomId("action")
                .setPlaceholder("Perform an action")
                .addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Edit")
                        .setDescription("Edit this page")
                        .setValue("edit")
                        .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Delete")
                        .setDescription("Delete this page")
                        .setValue("delete")
                        .setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji)
                );
        }
        const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId("back")
                .setStyle(ButtonStyle.Primary)
                .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji)
                .setDisabled(page === 0),
            new ButtonBuilder()
                .setCustomId("next")
                .setEmoji(getEmojiByName("CONTROL.RIGHT", "id") as APIMessageComponentEmoji)
                .setStyle(ButtonStyle.Primary)
                .setDisabled(page === Object.keys(currentObject.options).length || noRoleMenus),
            new ButtonBuilder()
                .setCustomId("add")
                .setLabel("New Page")
                .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id") as APIMessageComponentEmoji)
                .setStyle(ButtonStyle.Secondary)
                .setDisabled(Object.keys(currentObject.options).length >= 24),
            new ButtonBuilder()
                .setCustomId("reorder")
                .setLabel("Reorder Pages")
                .setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji)
                .setStyle(ButtonStyle.Secondary)
                .setDisabled(Object.keys(currentObject.options).length <= 1),
            new ButtonBuilder()
                .setCustomId("save")
                .setLabel("Save")
                .setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji)
                .setStyle(ButtonStyle.Success)
                .setDisabled(!modified)
        );
        if (noRoleMenus) {
            embed.setDescription(
                "No role menu pages have been set up yet. Use the button below to add one.\n\n" +
                    createPageIndicator(1, 1, undefined, true)
            );
            pageSelect.setDisabled(true);
            if (page > 0) (actionSelect as StringSelectMenuBuilder).setDisabled(true);
            pageSelect.addOptions(new StringSelectMenuOptionBuilder().setLabel("No role menu pages").setValue("none"));
        } else if (page === 0) {
            embed.setDescription(
                `**Enabled:** ${currentObject.enabled ? `${tick} Yes` : `${cross} No`}\n\n` +
                    `**Pages:** ${currentObject.options.length}\n` +
                    (currentObject.options.length > 0
                        ? currentObject.options
                              .map((key: ObjectSchema) => {
                                  const crossOut = key.enabled ? "" : "~~";
                                  return `> ${crossOut}**${key.name}:** ${
                                      key.description ?? "*No description set*"
                                  }${crossOut}`;
                              })
                              .join("\n")
                        : "")
            );
            if (currentObject.options.length > 0) {
                pageSelect.addOptions(
                    currentObject.options.map((key: ObjectSchema, index) => {
                        return new StringSelectMenuOptionBuilder()
                            .setLabel(ellipsis(key.name, 50))
                            .setDescription(
                                ellipsis(
                                    key.description?.length
                                        ? key.description.length > 0
                                            ? key.description
                                            : "No description set"
                                        : "No description set",
                                    50
                                )
                            )
                            .setValue((index + 1).toString());
                    })
                );
            } else {
                pageSelect.setDisabled(true);
                pageSelect.addOptions(
                    new StringSelectMenuOptionBuilder().setLabel("No role menu pages").setValue("none")
                );
            }
        } else {
            page = Math.max(Math.min(page, currentObject.options.length), 0);
            current = currentObject.options[page - 1]!;
            (actionSelect as StringSelectMenuBuilder).addOptions(
                new StringSelectMenuOptionBuilder()
                    .setLabel(current.enabled ? "Disable" : "Enable")
                    .setDescription("Enable or disable this page")
                    .setValue("switch")
                    .setEmoji(
                        getEmojiByName(
                            current.enabled ? "CONTROL.CROSS" : "CONTROL.TICK",
                            "id"
                        ) as APIMessageComponentEmoji
                    )
            );
            embed.setDescription(
                `**Currently Editing:** ${current.name}\n\n` +
                    `**Visible:** ${current.enabled ? `${tick} Yes` : `${cross} No`}\n\n` +
                    `**Description:**\n> ${current.description ?? "*No description set*"}\n` +
                    `\n\n${createPageIndicator(
                        Object.keys(currentObject.options).length,
                        page - 1,
                        false,
                        Object.values(currentObject.options).map((o) => !(o.enabled ?? true))
                    )}`
            );

            pageSelect.addOptions(
                currentObject.options.map((key: ObjectSchema, index) => {
                    return new StringSelectMenuOptionBuilder()
                        .setLabel(ellipsis(key.name, 50))
                        .setDescription(
                            ellipsis(
                                key.description?.length
                                    ? key.description.length > 0
                                        ? key.description
                                        : "No description set"
                                    : "No description set",
                                50
                            )
                        )
                        .setValue((index + 1).toString());
                })
            );
        }

        await interaction.editReply({
            embeds: [embed],
            components: [
                page === 0
                    ? (actionSelect as ActionRowBuilder<ButtonBuilder>)
                    : new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
                          actionSelect as StringSelectMenuBuilder
                      ),
                new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(pageSelect),
                buttonRow as ActionRowBuilder<ButtonBuilder>
            ]
        });
        let i: StringSelectMenuInteraction | ButtonInteraction;
        try {
            i = (await m.awaitMessageComponent({
                time: 300000,
                filter: (i) =>
                    i.user.id === interaction.user.id && i.message.id === m.id && i.channelId === interaction.channelId
            })) as ButtonInteraction | StringSelectMenuInteraction;
        } catch (e) {
            closed = true;
            continue;
        }

        await i.deferUpdate();
        if (i.isButton()) {
            switch (i.customId) {
                case "back": {
                    page--;
                    break;
                }
                case "next": {
                    page++;
                    break;
                }
                case "add": {
                    const newPage = await editRoleMenuPage(i, m);
                    if (_.isEqual(newPage, defaultRoleMenuData)) {
                        break;
                    }
                    if (newPage) {
                        currentObject.options.push(newPage);
                        page = currentObject.options.length;
                        modified = true;
                    }
                    break;
                }
                case "reorder": {
                    const reordered = await reorderRoleMenuPages(interaction, m, currentObject.options);
                    if (!reordered) break;
                    currentObject.options = reordered;
                    modified = true;
                    break;
                }
                case "save": {
                    await client.database.guilds.write(interaction.guild.id, {
                        roleMenu: currentObject
                    });
                    modified = false;
                    await client.memory.forceUpdate(interaction.guild.id);
                    break;
                }
                case "switch": {
                    currentObject.enabled = !currentObject.enabled;
                    modified = true;
                    break;
                }
            }
        } else if (i.isStringSelectMenu()) {
            switch (i.customId) {
                case "action": {
                    switch (i.values[0]) {
                        case "edit": {
                            const edited = await editRoleMenuPage(i, m, current!);
                            if (!edited) break;
                            currentObject.options[page - 1] = edited;
                            modified = true;
                            break;
                        }
                        case "delete": {
                            if (page === 0 && currentObject.options.keys.length - 1 > 0) page++;
                            else page--;
                            currentObject.options.splice(page, 1);
                            modified = true;
                            break;
                        }
                        case "switch": {
                            currentObject.options[page - 1]!.enabled = !currentObject.options[page - 1]!.enabled;
                            modified = true;
                            break;
                        }
                    }
                    break;
                }
                case "page": {
                    page = parseInt(i.values[0]!);
                    break;
                }
            }
        }
    } while (!closed);
    await interaction.deleteReply();
};

const check = (interaction: CommandInteraction, _partial: boolean = false) => {
    const member = interaction.member as Discord.GuildMember;
    if (!member.permissions.has("ManageRoles"))
        return "You must have the *Manage Roles* permission to use this command";
    return true;
};

export { command };
export { callback };
export { check };
