import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, GuildMember, Message, ActionRowBuilder, ButtonBuilder, ButtonStyle, APIMessageComponentEmoji, StringSelectMenuBuilder, MessageComponentInteraction, StringSelectMenuInteraction, StringSelectMenuOptionBuilder } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import addPlural from "../../utils/plurals.js";
import client from "../../utils/client.js";
import { createVerticalTrack } from "../../utils/createPageIndicator.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 callback = async (interaction: CommandInteraction): Promise<unknown> => {
    const { renderUser, renderRole} = 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.length)
            managed = data.manageableBy.some((element: string) => {
                return memberRoles.cache.has(element);
            });
        else managed = false;
        const dropdown = new Discord.StringSelectMenuBuilder()
            .addOptions(
                config.tracks.map((option, index) => {
                    const hasRoleInTrack: boolean = option.track.some((element: string) => {
                        return memberRoles.cache.has(element);
                    });
                    return new StringSelectMenuOptionBuilder({
                        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")
                        ) as APIMessageComponentEmoji
                    });
                })
            )
            .setCustomId("select")
            .setMaxValues(1);
        const allowed: boolean[] = [];
        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";
        for (const role of data.track) {
            const disabled: boolean =
                roles.get(role)!.position >= (interaction.member as GuildMember).roles.highest.position && !managed;
            allowed.push(!disabled)
        }
        generated += "\n" + createVerticalTrack(
            data.track.map((role) => renderRole(roles.get(role)!)),
            data.track.map((role) => memberRoles.cache.has(role)),
            allowed.map((allow) => !allow)
        );
        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: StringSelectMenuBuilder[] = [];
        const conflictDropdownOptions: StringSelectMenuOptionBuilder[] = [];
        let currentRoleIndex: number = -1;
        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) => {
                    conflictDropdownOptions.push(
                        new StringSelectMenuOptionBuilder()
                            .setLabel(roles.get(role)!.name)
                            .setValue(roles.get(role)!.id)
                    );
                });
                conflictDropdown = [
                    new Discord.StringSelectMenuBuilder()
                        .addOptions(conflictDropdownOptions)
                        .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<StringSelectMenuBuilder | ButtonBuilder>().addComponents(dropdown)]
                .concat(
                    conflict && conflictDropdown.length ? [new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(conflictDropdown)] : []
                )
                .concat([
                    new ActionRowBuilder<ButtonBuilder>().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: MessageComponentInteraction;
        try {
            component = await m.awaitMessageComponent({
                time: 300000,
                filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id && i.message.id === m.id }
            });
        } catch (e) {
            timedOut = true;
            continue;
        }
        component.deferUpdate();
        if (component.customId === "conflict") {
            const rolesToRemove = selected.filter((role) => role !== (component as StringSelectMenuInteraction).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 = parseInt((component as StringSelectMenuInteraction).values[0]!);
        }
    }
};

const check = async (interaction: CommandInteraction, _partial: boolean = false) => {
    const tracks = (await client.database.guilds.read(interaction.guild!.id)).tracks;
    if (tracks.length === 0) return "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;
    const memberRoles = member.roles.cache.map((r) => r.id)
    for (const element of tracks) {
        if (!element.manageableBy.length) continue;
        if (!element.manageableBy.some((role: string) => memberRoles.includes(role))) continue;
        managed = true;
        break;
    }
    // Check if the user has manage_roles permission
    if (!managed && !member.permissions.has("ManageRoles")) return "You do not have the *Manage Roles* permission";
    // Allow track
    return true;
};

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