import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
import Discord, {
    CommandInteraction,
    GuildMember,
    Message,
    MessageActionRow,
    MessageButton
} from "discord.js";
import {
    SelectMenuOption,
    SlashCommandSubcommandBuilder
} from "@discordjs/builders";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
import { WrappedCheck } from "jshaiku";
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<void | 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 = await member.roles;
    let managed: boolean;
    while (true) {
        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.MessageSelectMenu()
            .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 (let i = 0; i < data.track.length; i++) {
            if (memberRoles.cache.has(data.track[i]))
                selected.push(data.track[i]);
        }
        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.MessageSelectMenu()
                        .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 MessageActionRow().addComponents(dropdown)]
                .concat(
                    conflict && conflictDropdown.length
                        ? [
                              new MessageActionRow().addComponents(
                                  conflictDropdown
                              )
                          ]
                        : []
                )
                .concat([
                    new MessageActionRow().addComponents([
                        new MessageButton()
                            .setEmoji(getEmojiByName("CONTROL.UP", "id"))
                            .setLabel("Move up")
                            .setCustomId("promote")
                            .setStyle("SUCCESS")
                            .setDisabled(
                                conflict ||
                                    currentRoleIndex === 0 ||
                                    (currentRoleIndex === -1
                                        ? false
                                        : !allowed[currentRoleIndex - 1])
                            ),
                        new MessageButton()
                            .setEmoji(getEmojiByName("CONTROL.DOWN", "id"))
                            .setLabel("Move down")
                            .setCustomId("demote")
                            .setStyle("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 });
        } catch (e) {
            return;
        }
        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,
    _defaultCheck: WrappedCheck
) => {
    const tracks = (await client.database.guilds.read(interaction.guild.id))
        .tracks;
    if (tracks.length === 0) throw "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 "You do not have the *Manage Roles* permission";
    // Allow track
    return true;
};

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