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);
        current.name = "Default";
    }

    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[] = _.cloneDeep(config.tracks);
    const roles = await interaction.guild!.roles.fetch();

    let page = 0;
    let closed = false;

    do {
        const embed = new EmojiEmbed().setTitle("Track Settings").setEmoji("TRACKS.ICON").setStatus("Success");
        const noTracks = 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(_.isEqual(tracks, config.tracks))
        );
        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;
                    if (!newPage) break;
                    tracks.push(newPage);
                    page = tracks.length - 1;
                    break;
                }
                case "save": {
                    await client.database.guilds.write(interaction.guild!.id, { tracks: tracks });
                    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;
                            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 };
