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 isEqual = _.isEqual;

const command = (builder: SlashCommandSubcommandBuilder) => builder.setName("rolemenu").setDescription("rolemenu");

interface ObjectSchema {
    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 }
) => {
    let { name, description } = data;
    const modal = new ModalBuilder()
        .setTitle("Edit Name and Description")
        .setCustomId("editNameDescription")
        .addComponents(
            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)
            ),
            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 ?? "")
            )
        );
    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];
    if (out.isButton()) return [name, description];
    name = out.fields.fields.find((f) => f.customId === "name")?.value ?? name;
    description = out.fields.fields.find((f) => f.customId === "description")?.value ?? description;
    return [name, description];
};

const defaultRoleMenuData = {
    name: "Role Menu Page",
    description: "A new role menu page",
    min: 0,
    max: 0,
    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;
    if (data.options.length === 0) {
        data.options = [{ name: "Role 1", description: null, role: "No role set" }];
    }
    do {
        const previewSelect = configToDropdown("Edit Roles", {
            name: data.name,
            description: data.description,
            min: 1,
            max: 1,
            options: data.options
        });
        const embed = new EmojiEmbed()
            .setTitle(`${data.name}`)
            .setStatus("Success")
            .setDescription(
                `**Description:**\n> ${data.description}\n\n` +
                    `**Min:** ${data.min}` +
                    (data.min === 0 ? " (Members will be given a skip button)" : "") +
                    "\n" +
                    `**Max:** ${data.max}\n`
            );

        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])
                );
            }
        } 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);
                    data.name = name ? name : data.name;
                    data.description = description ? description : data.description;
                    break;
                }
                case "addRole": {
                    await i.deferUpdate();
                    data.options.push(await createRoleMenuOptionPage(interaction, m));
                    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 }
) => {
    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("Back")
            .setStyle(ButtonStyle.Secondary)
            .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
        new ButtonBuilder()
            .setCustomId("edit")
            .setLabel("Edit Details")
            .setStyle(ButtonStyle.Primary)
            .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji)
    );
    do {
        const roleSelect = new RoleSelectMenuBuilder()
            .setCustomId("role")
            .setPlaceholder(data.role ? "Set role to" : "Set the 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]!;
            }
        } else if (i.isButton()) {
            switch (i.customId) {
                case "back": {
                    await i.deferUpdate();
                    back = true;
                    break;
                }
                case "edit": {
                    await i.deferUpdate();
                    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;
                }
            }
        }
    } 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);
    let currentObject: ObjectSchema[] = _.cloneDeep(config.roleMenu.options);
    let modified = false;
    do {
        const embed = new EmojiEmbed().setTitle("Role Menu").setEmoji("GUILD.GREEN").setStatus("Success");
        const noRoleMenus = currentObject.length === 0;
        let current: ObjectSchema;

        const pageSelect = new StringSelectMenuBuilder()
            .setCustomId("page")
            .setPlaceholder("Select a Role Menu page to manage");
        const 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).length - 1 || noRoleMenus),
            new ButtonBuilder()
                .setCustomId("add")
                .setLabel("New Page")
                .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id") as APIMessageComponentEmoji)
                .setStyle(ButtonStyle.Secondary)
                .setDisabled(Object.keys(currentObject).length >= 24),
            new ButtonBuilder()
                .setCustomId("reorder")
                .setLabel("Reorder Pages")
                .setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji)
                .setStyle(ButtonStyle.Secondary)
                .setDisabled(Object.keys(currentObject).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);
            actionSelect.setDisabled(true);
            pageSelect.addOptions(new StringSelectMenuOptionBuilder().setLabel("No role menu pages").setValue("none"));
        } else {
            page = Math.min(page, Object.keys(currentObject).length - 1);
            current = currentObject[page]!;
            embed.setDescription(
                `**Currently Editing:** ${current.name}\n\n` +
                    `**Description:**\n> ${current.description}\n` +
                    `\n\n${createPageIndicator(Object.keys(config.roleMenu.options).length, page)}`
            );

            pageSelect.addOptions(
                currentObject.map((key: ObjectSchema, index) => {
                    return new StringSelectMenuOptionBuilder()
                        .setLabel(ellipsis(key.name, 50))
                        .setDescription(ellipsis(key.description, 50))
                        .setValue(index.toString());
                })
            );
        }

        await interaction.editReply({
            embeds: [embed],
            components: [
                new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(actionSelect),
                new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(pageSelect),
                buttonRow
            ]
        });
        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;
                    currentObject.push();
                    page = currentObject.length - 1;
                    break;
                }
                case "reorder": {
                    const reordered = await reorderRoleMenuPages(interaction, m, currentObject);
                    if (!reordered) break;
                    currentObject = reordered;
                    break;
                }
                case "save": {
                    await client.database.guilds.write(interaction.guild.id, { "roleMenu.options": currentObject });
                    modified = false;
                    await client.memory.forceUpdate(interaction.guild.id);
                    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[page] = edited;
                            modified = true;
                            break;
                        }
                        case "delete": {
                            if (page === 0 && currentObject.keys.length - 1 > 0) page++;
                            else page--;
                            currentObject.splice(page, 1);
                            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 };
