import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, GuildMember, Message, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import addPlural from "../../utils/plurals.js";
import client from "../../utils/client.js";

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("track")
        .setDescription("Moves a user along a role track")
        .addUserOption((option) => option.setName("user").setDescription("The user to manage").setRequired(true));

const generateFromTrack = (position: number, active: string | boolean, size: number, disabled: string | boolean) => {
    active = active ? "ACTIVE" : "INACTIVE";
    disabled = disabled ? "GREY." : "";
    if (position === 0 && size === 1) return "TRACKS.SINGLE." + disabled + active;
    if (position === size - 1) return "TRACKS.VERTICAL.BOTTOM." + disabled + active;
    if (position === 0) return "TRACKS.VERTICAL.TOP." + disabled + active;
    return "TRACKS.VERTICAL.MIDDLE." + disabled + active;
};

const callback = async (interaction: CommandInteraction): Promise<unknown> => {
    const { renderUser } = client.logger;
    const member = interaction.options.getMember("user") as GuildMember;
    const guild = interaction.guild;
    if (!guild) return;
    const config = await client.database.guilds.read(guild.id);
    await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
    let track = 0;
    let generated;
    const roles = await guild.roles.fetch();
    const memberRoles = member.roles;
    let managed: boolean;
    let timedOut = false;
    while (!timedOut) {
        const data = config.tracks[track];
        if (data.manageableBy !== undefined)
            managed = data.manageableBy.some((element: string) => {
                return memberRoles.cache.has(element);
            });
        else managed = false;
        const dropdown = new Discord.SelectMenuBuilder()
            .addOptions(
                config.tracks.map((option, index) => {
                    const hasRoleInTrack = option.track.some((element: string) => {
                        return memberRoles.cache.has(element);
                    });
                    return new SelectMenuOption({
                        default: index === track,
                        label: option.name,
                        value: index.toString(),
                        description: option.track.length === 0 ? "No" : addPlural(option.track.length, "role"),
                        emoji: client.emojis.resolve(
                            getEmojiByName("TRACKS.SINGLE." + (hasRoleInTrack ? "ACTIVE" : "INACTIVE"), "id")
                        )
                    });
                })
            )
            .setCustomId("select")
            .setMaxValues(1);
        const allowed = [];
        generated = "**Track:** " + data.name + "\n" + "**Member:** " + renderUser(member.user) + "\n";
        generated +=
            (data.nullable ? "Members do not need a role in this track" : "A role in this track is required") + "\n";
        generated +=
            (data.retainPrevious
                ? "When promoted, the user keeps previous roles"
                : "Members will lose their current role when promoted") + "\n";
        generated +=
            "\n" +
            data.track
                .map((role, index) => {
                    const allow =
                        roles.get(role).position >= (interaction.member as GuildMember).roles.highest.position &&
                        !managed;
                    allowed.push(!allow);
                    return (
                        getEmojiByName(
                            generateFromTrack(index, memberRoles.cache.has(role), data.track.length, allow)
                        ) +
                        " " +
                        roles.get(role).name +
                        " [<@&" +
                        roles.get(role).id +
                        ">]"
                    );
                })
                .join("\n");
        const selected = [];
        for (const position of data.track) {
            if (memberRoles.cache.has(position)) selected.push(position);
        }
        const conflict = data.retainPrevious ? false : selected.length > 1;
        let conflictDropdown;
        let currentRoleIndex;
        if (conflict) {
            generated += `\n\n${getEmojiByName(`PUNISH.WARN.${managed ? "YELLOW" : "RED"}`)} This user has ${
                selected.length
            } roles from this track. `;
            conflictDropdown = [];
            if (roles.get(selected[0]).position < memberRoles.highest.position || managed) {
                generated +=
                    "In order to promote or demote this user, you must select which role the member should keep.";
                selected.forEach((role) => {
                    conflictDropdown.push(
                        new SelectMenuOption({
                            label: roles.get(role).name,
                            value: roles.get(role).id
                        })
                    );
                });
                conflictDropdown = [
                    new Discord.SelectMenuBuilder()
                        .addOptions(conflictDropdown)
                        .setCustomId("conflict")
                        .setMaxValues(1)
                        .setPlaceholder("Select a role to keep")
                ];
            } else {
                generated +=
                    "You don't have permission to manage one or more of the users roles, and therefore can't select one to keep.";
            }
        } else {
            currentRoleIndex = selected.length === 0 ? -1 : data.track.indexOf(selected[0].toString());
        }
        const m = (await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("TRACKS.ICON")
                    .setTitle("Tracks")
                    .setDescription(`${generated}`)
                    .setStatus("Success")
            ],
            components: [new ActionRowBuilder().addComponents(dropdown)]
                .concat(
                    conflict && conflictDropdown.length ? [new ActionRowBuilder().addComponents(conflictDropdown)] : []
                )
                .concat([
                    new ActionRowBuilder().addComponents([
                        new ButtonBuilder()
                            .setEmoji(getEmojiByName("CONTROL.UP", "id"))
                            .setLabel("Move up")
                            .setCustomId("promote")
                            .setStyle(ButtonStyle.Success)
                            .setDisabled(
                                conflict ||
                                    currentRoleIndex === 0 ||
                                    (currentRoleIndex === -1 ? false : !allowed[currentRoleIndex - 1])
                            ),
                        new ButtonBuilder()
                            .setEmoji(getEmojiByName("CONTROL.DOWN", "id"))
                            .setLabel("Move down")
                            .setCustomId("demote")
                            .setStyle(ButtonStyle.Danger)
                            .setDisabled(
                                conflict ||
                                    (data.nullable
                                        ? currentRoleIndex <= -1
                                        : currentRoleIndex === data.track.length - 1 || currentRoleIndex <= -1) ||
                                    !allowed[currentRoleIndex]
                            )
                    ])
                ])
        })) as Message;
        let component;
        try {
            component = await m.awaitMessageComponent({
                time: 300000,
                filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
            });
        } catch (e) {
            timedOut = true;
            continue;
        }
        component.deferUpdate();
        if (component.customId === "conflict") {
            const rolesToRemove = selected.filter((role) => role !== component.values[0]);
            await member.roles.remove(rolesToRemove);
        } else if (component.customId === "promote") {
            if (
                currentRoleIndex === -1
                    ? allowed[data.track.length - 1]
                    : allowed[currentRoleIndex - 1] && allowed[currentRoleIndex]
            ) {
                if (currentRoleIndex === -1) {
                    await member.roles.add(data.track[data.track.length - 1]);
                } else if (currentRoleIndex < data.track.length) {
                    if (!data.retainPrevious) await member.roles.remove(data.track[currentRoleIndex]);
                    await member.roles.add(data.track[currentRoleIndex - 1]);
                }
            }
        } else if (component.customId === "demote") {
            if (allowed[currentRoleIndex]) {
                if (currentRoleIndex === data.track.length - 1) {
                    if (data.nullable) await member.roles.remove(data.track[currentRoleIndex]);
                } else if (currentRoleIndex > -1) {
                    await member.roles.remove(data.track[currentRoleIndex]);
                    await member.roles.add(data.track[currentRoleIndex + 1]);
                }
            }
        } else if (component.customId === "select") {
            track = component.values[0];
        }
    }
};

const check = async (interaction: CommandInteraction) => {
    const tracks = (await client.database.guilds.read(interaction.guild.id)).tracks;
    if (tracks.length === 0) throw new Error("This server does not have any tracks");
    const member = interaction.member as GuildMember;
    // Allow the owner to promote anyone
    if (member.id === interaction.guild.ownerId) return true;
    // Check if the user can manage any of the tracks
    let managed = false;
    for (const element of tracks) {
        if (!element.track.manageableBy) continue;
        if (!element.track.manageableBy.some((role) => member.roles.cache.has(role))) continue;
        managed = true;
        break;
    }
    // Check if the user has manage_roles permission
    if (!managed && !member.permissions.has("MANAGE_ROLES"))
        throw new Error("You do not have the *Manage Roles* permission");
    // Allow track
    return true;
};

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