import {
    ActionRowBuilder,
    APIMessageComponentEmoji,
    ButtonBuilder,
    ButtonInteraction,
    ButtonStyle,
    Collection,
    CommandInteraction,
    GuildMember,
    Message,
    ModalBuilder,
    ModalSubmitInteraction,
    PermissionsBitField,
    Role,
    RoleSelectMenuBuilder,
    RoleSelectMenuInteraction,
    SlashCommandSubcommandBuilder,
    StringSelectMenuBuilder,
    StringSelectMenuInteraction,
    StringSelectMenuOptionBuilder,
    TextInputBuilder,
    TextInputStyle
} from "discord.js";
import client from "../../utils/client.js";
import createPageIndicator, { createVerticalTrack } from "../../utils/createPageIndicator.js";
import { LoadingEmbed } from "../../utils/defaults.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import ellipsis from "../../utils/ellipsis.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
import _ from "lodash";

const { renderRole } = client.logger;

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder.setName("tracks").setDescription("Manage the tracks for the server");

interface ObjectSchema {
    name: string;
    retainPrevious: boolean;
    nullable: boolean;
    track: string[];
    manageableBy: string[];
}

const editName = async (
    i: ButtonInteraction,
    interaction: StringSelectMenuInteraction | ButtonInteraction,
    m: Message,
    current?: string
) => {
    let name = current ?? "";
    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 track (e.g. Moderators)")
                    .setStyle(TextInputStyle.Short)
                    .setValue(name)
                    .setRequired(true)
            )
        );
    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("Tracks")
                .setDescription("Modal opened. If you can't see it, click back and try again.")
                .setStatus("Success")
        ],
        components: [button]
    });

    let out: ModalSubmitInteraction | null;
    try {
        out = (await modalInteractionCollector(m, interaction.user)) as ModalSubmitInteraction | null;
    } catch (e) {
        console.error(e);
        out = null;
    }
    if (!out) return name;
    if (out.isButton()) return name;
    name = out.fields.fields.find((f) => f.customId === "name")?.value ?? name;
    return name;
};

const reorderTracks = async (
    interaction: ButtonInteraction | StringSelectMenuInteraction,
    buttonInteraction: ButtonInteraction,
    m: Message,
    roles: Collection<string, Role>,
    currentObj: string[]
) => {
    const reorderRow = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
        new StringSelectMenuBuilder()
            .setCustomId("reorder")
            .setPlaceholder("Select all roles in the order you want users to gain them (Lowest to highest rank).")
            .setMinValues(currentObj.length)
            .setMaxValues(currentObj.length)
            .addOptions(
                currentObj.map((o, i) =>
                    new StringSelectMenuOptionBuilder().setLabel(roles.get(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("Tracks")
                .setDescription("Select all roles in the order you want users to gain them (Lowest to highest rank).")
                .setStatus("Success")
        ],
        components: [reorderRow, buttonRow]
    });
    let out: StringSelectMenuInteraction | ButtonInteraction | null;
    try {
        out = (await m.awaitMessageComponent({
            filter: (i) => i.channel!.id === buttonInteraction.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: string[] = currentObj.map((_, i) => {
        const index = values.findIndex((v) => v === i.toString());
        return currentObj[index];
    }) as string[];

    return newOrder;
};

const defaultTrackData = {
    name: "",
    retainPrevious: false,
    nullable: true,
    track: [],
    manageableBy: []
};

const editTrack = async (
    interaction: ButtonInteraction | StringSelectMenuInteraction,
    message: Message,
    roles: Collection<string, Role>,
    current?: ObjectSchema
) => {
    const isAdmin = (interaction.member!.permissions as PermissionsBitField).has("Administrator");
    if (!current) {
        current = _.cloneDeep(defaultTrackData);
    }

    const roleSelect = new ActionRowBuilder<RoleSelectMenuBuilder>().addComponents(
        new RoleSelectMenuBuilder().setCustomId("addRole").setPlaceholder("Select a role to add").setDisabled(!isAdmin)
    );
    let closed = false;
    let previousMessage = "";
    do {
        const editableRoles: string[] = current.track
            .map((r) => {
                if (
                    !(roles.get(r)!.position >= (interaction.member as GuildMember).roles.highest.position) ||
                    interaction.user.id === interaction.guild?.ownerId
                )
                    return roles.get(r)!.name;
            })
            .filter((v) => v !== undefined) as string[];
        const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("removeRole")
                .setPlaceholder("Select a role to remove")
                .setDisabled(!isAdmin)
                .addOptions(
                    editableRoles.map((r, i) => {
                        return new StringSelectMenuOptionBuilder().setLabel(r).setValue(i.toString());
                    })
                )
        );
        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 Name")
                .setStyle(ButtonStyle.Primary)
                .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("reorder")
                .setLabel("Reorder")
                .setDisabled(!isAdmin)
                .setStyle(ButtonStyle.Primary)
                .setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("retainPrevious")
                .setLabel("Retain Previous")
                .setStyle(current.retainPrevious ? ButtonStyle.Success : ButtonStyle.Danger)
                .setEmoji(
                    getEmojiByName(
                        "CONTROL." + (current.retainPrevious ? "TICK" : "CROSS"),
                        "id"
                    ) as APIMessageComponentEmoji
                ),
            new ButtonBuilder()
                .setCustomId("nullable")
                .setLabel(`Role ${current.nullable ? "Not " : ""}Required`)
                .setStyle(current.nullable ? ButtonStyle.Danger : ButtonStyle.Success)
                .setEmoji(
                    getEmojiByName("CONTROL." + (current.nullable ? "CROSS" : "TICK"), "id") as APIMessageComponentEmoji
                )
        );

        const allowed: boolean[] = [];
        for (const role of current.track) {
            const disabled: boolean =
                roles.get(role)!.position >= (interaction.member as GuildMember).roles.highest.position;
            allowed.push(disabled);
        }
        const mapped = current.track.map((role) => roles.find((aRole) => aRole.id === role)!);

        const embed = new EmojiEmbed()
            .setTitle("Tracks")
            .setDescription(
                `**Currently Editing:** ${current.name}\n\n` +
                    `${getEmojiByName("CONTROL." + (current.nullable ? "CROSS" : "TICK"))} Members ${
                        current.nullable ? "don't " : ""
                    }need a role in this track\n` +
                    `${getEmojiByName("CONTROL." + (current.retainPrevious ? "TICK" : "CROSS"))} Members ${
                        current.retainPrevious ? "" : "don't "
                    }keep all roles below their current highest\n\n` +
                    (previousMessage ? previousMessage + "\n\n" : "") +
                    createVerticalTrack(
                        mapped.map((role) => renderRole(role)),
                        new Array(current.track.length).fill(false),
                        allowed
                    )
            )
            .setStatus("Success");

        const comps: ActionRowBuilder<RoleSelectMenuBuilder | ButtonBuilder | StringSelectMenuBuilder>[] = [
            roleSelect,
            buttons
        ];
        if (current.track.length >= 1) comps.splice(1, 0, selectMenu);

        await interaction.editReply({ embeds: [embed], components: comps });

        let out: ButtonInteraction | RoleSelectMenuInteraction | StringSelectMenuInteraction | null;

        try {
            out = (await message.awaitMessageComponent({
                filter: (i) => i.channel!.id === interaction.channel!.id,
                time: 300000
            })) as ButtonInteraction | RoleSelectMenuInteraction | StringSelectMenuInteraction | null;
        } catch (e) {
            console.error(e);
            out = null;
        }

        if (!out) return;
        if (out.isButton()) {
            switch (out.customId) {
                case "back": {
                    await out.deferUpdate();
                    closed = true;
                    break;
                }
                case "edit": {
                    current.name = (await editName(out, interaction, message, current.name))!;
                    break;
                }
                case "reorder": {
                    await out.deferUpdate();
                    current.track = (await reorderTracks(interaction, out, message, roles, current.track))!;
                    break;
                }
                case "retainPrevious": {
                    await out.deferUpdate();
                    current.retainPrevious = !current.retainPrevious;
                    break;
                }
                case "nullable": {
                    await out.deferUpdate();
                    current.nullable = !current.nullable;
                    break;
                }
            }
        } else if (out.isStringSelectMenu()) {
            await out.deferUpdate();
            switch (out.customId) {
                case "removeRole": {
                    const index = current.track.findIndex(
                        (v) => v === editableRoles[parseInt((out! as StringSelectMenuInteraction).values![0]!)]
                    );
                    current.track.splice(index, 1);
                    break;
                }
            }
        } else {
            await out.deferUpdate();
            switch (out.customId) {
                case "addRole": {
                    const role = out.values![0]!;
                    const roleObj = roles.get(role)!;
                    if (roleObj.position >= (interaction.member as GuildMember).roles.highest.position) {
                        previousMessage = "You can't add a role that is higher than your highest role.";
                    } else {
                        if (!current.track.includes(role)) {
                            current.track.push(role);
                        } else {
                            previousMessage = "That role is already on this track";
                        }
                    }
                    await interaction.editReply({ embeds: LoadingEmbed, components: [] });
                    break;
                }
            }
        }
    } while (!closed);
    return current;
};

const callback = async (interaction: CommandInteraction) => {
    const m = await interaction.reply({ embeds: LoadingEmbed, fetchReply: true, ephemeral: true });
    const config = await client.database.guilds.read(interaction.guild!.id);
    const tracks: ObjectSchema[] = config.tracks;
    const roles = await interaction.guild!.roles.fetch();

    let page = 0;
    let closed = false;
    let modified = false;

    do {
        const embed = new EmojiEmbed().setTitle("Track Settings").setEmoji("TRACKS.ICON").setStatus("Success");
        const noTracks = config.tracks.length === 0;
        let current: ObjectSchema;

        const pageSelect = new StringSelectMenuBuilder().setCustomId("page").setPlaceholder("Select a track to manage");
        const actionSelect = new StringSelectMenuBuilder()
            .setCustomId("action")
            .setPlaceholder("Perform an action")
            .addOptions(
                new StringSelectMenuOptionBuilder()
                    .setLabel("Edit")
                    .setDescription("Edit this track")
                    .setValue("edit")
                    .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
                new StringSelectMenuOptionBuilder()
                    .setLabel("Delete")
                    .setDescription("Delete this track")
                    .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 === tracks.length - 1 || noTracks),
            new ButtonBuilder()
                .setCustomId("add")
                .setLabel("New Track")
                .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id") as APIMessageComponentEmoji)
                .setStyle(ButtonStyle.Secondary)
                .setDisabled(Object.keys(tracks).length >= 24),
            new ButtonBuilder()
                .setCustomId("save")
                .setLabel("Save")
                .setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji)
                .setStyle(ButtonStyle.Success)
                .setDisabled(!modified)
        );
        if (noTracks) {
            embed.setDescription(
                "No tracks 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 tracks").setValue("none"));
        } else {
            page = Math.min(page, Object.keys(tracks).length - 1);
            current = tracks[page]!;
            const mapped = current.track.map((role) => roles.find((aRole) => aRole.id === role)!);
            embed.setDescription(
                `**Currently Editing:** ${current.name}\n\n` +
                    `${getEmojiByName("CONTROL." + (current.nullable ? "CROSS" : "TICK"))} Members ${
                        current.nullable ? "don't " : ""
                    }need a role in this track\n` +
                    `${getEmojiByName("CONTROL." + (current.retainPrevious ? "TICK" : "CROSS"))} Members ${
                        current.retainPrevious ? "" : "don't "
                    }keep all roles below their current highest\n\n` +
                    createVerticalTrack(
                        mapped.map((role) => renderRole(role)),
                        new Array(current.track.length).fill(false)
                    ) +
                    `\n${createPageIndicator(config.tracks.length, page)}`
            );

            pageSelect.addOptions(
                tracks.map((key: ObjectSchema, index) => {
                    return new StringSelectMenuOptionBuilder()
                        .setLabel(ellipsis(key.name, 50))
                        .setDescription(ellipsis(roles.get(key.track[0]!)?.name!, 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 editTrack(i, m, roles);
                    if (_.isEqual(newPage, defaultTrackData)) break;
                    tracks.push();
                    page = tracks.length - 1;
                    break;
                }
                case "save": {
                    await client.database.guilds.write(interaction.guild!.id, { tracks: tracks });
                    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 editTrack(i, m, roles, current!);
                            if (!edited) break;
                            tracks[page] = edited;
                            modified = true;
                            break;
                        }
                        case "delete": {
                            if (page === 0 && tracks.keys.length - 1 > 0) page++;
                            else page--;
                            tracks.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 GuildMember;
    if (!member.permissions.has("ManageRoles"))
        return "You must have the *Manage Server* permission to use this command";
    return true;
};

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