import { ActionRowBuilder, APIMessageComponentEmoji, ButtonBuilder, ButtonInteraction, ButtonStyle, CommandInteraction, GuildMember, Role, RoleSelectMenuBuilder, RoleSelectMenuInteraction, UserSelectMenuBuilder, UserSelectMenuInteraction } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js";
import client from "../../utils/client.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import { LoadingEmbed } from "../../utils/defaults.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import listToAndMore from "../../utils/listToAndMore.js"

const { renderUser } = client.logger;

const canEdit = (role: Role, member: GuildMember, me: GuildMember): [string, boolean] => {
    if(role.position >= me.roles.highest.position ||
       role.position >= member.roles.highest.position
    ) return [`~~<@&${role.id}>~~`, false];
    return [`<@&${role.id}>`, true];
};

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("role")
        .setDescription("Gives or removes a role from someone")
        .addUserOption((option) => option.setName("user").setDescription("The user to give or remove the role from"))

const callback = async (interaction: CommandInteraction): Promise<unknown> => {
    const m = await interaction.reply({ embeds: LoadingEmbed, fetchReply: true, ephemeral: true });

    let member = interaction.options.getMember("user") as GuildMember | null;

    if(!member) {
        const memberEmbed = new EmojiEmbed()
            .setTitle("Role")
            .setDescription(`Please choose a member to edit the roles of.`)
            .setEmoji("GUILD.ROLES.CREATE")
            .setStatus("Success");
        const memberChooser = new ActionRowBuilder<UserSelectMenuBuilder>().addComponents(
            new UserSelectMenuBuilder()
                .setCustomId("memberChooser")
                .setPlaceholder("Select a member")
        );
        await interaction.editReply({embeds: [memberEmbed], components: [memberChooser]});

        const filter = (i: UserSelectMenuInteraction) => i.customId === "memberChooser" && i.user.id === interaction.user.id;

        let i: UserSelectMenuInteraction | null;
        try {
            i = await m.awaitMessageComponent<5>({ filter, time: 300000});
        } catch (e) {
            return;
        }

        memberEmbed.setDescription(`Editing roles for ${renderUser(i.values[0]!)}`);
        await i.deferUpdate();
        await interaction.editReply({ embeds: LoadingEmbed, components: [] })
        member = await interaction.guild?.members.fetch(i.values[0]!)!;

    }

    let closed = false;
    let rolesToChange: string[] = [];
    const roleAdd = new ActionRowBuilder<RoleSelectMenuBuilder>()
        .addComponents(
            new RoleSelectMenuBuilder()
                .setCustomId("roleAdd")
                .setPlaceholder("Select a role to add")
                .setMaxValues(25)
        );

    do {

        const removing = rolesToChange.filter((r) => member!.roles.cache.has(r)).map((r) => canEdit(interaction.guild?.roles.cache.get(r)!, interaction.member as GuildMember, interaction.guild?.members.me!)[0])
        const adding = rolesToChange.filter((r) => !member!.roles.cache.has(r)).map((r) => canEdit(interaction.guild?.roles.cache.get(r)!, interaction.member as GuildMember, interaction.guild?.members.me!)[0])
        const embed = new EmojiEmbed()
        .setTitle("Role")
        .setDescription(
            `${getEmojiByName("ICONS.EDIT")} Editing roles for <@${member.id}>\n\n` +
            `Adding:\n` +
            `${listToAndMore(adding.length > 0 ? adding : ["None"], 5)}\n` +
            `Removing:\n` +
            `${listToAndMore(removing.length > 0 ? removing : ["None"], 5)}\n`
        )
        .setEmoji("GUILD.ROLES.CREATE")
        .setStatus("Success");

        const buttons = new ActionRowBuilder<ButtonBuilder>()
            .addComponents(
                new ButtonBuilder()
                    .setCustomId("roleSave")
                    .setLabel("Apply")
                    .setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji)
                    .setStyle(ButtonStyle.Success),
                new ButtonBuilder()
                    .setCustomId("roleDiscard")
                    .setLabel("Reset")
                    .setEmoji(getEmojiByName("CONTROL.CROSS", "id") as APIMessageComponentEmoji)
                    .setStyle(ButtonStyle.Danger)
            );

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

        let i: RoleSelectMenuInteraction | ButtonInteraction | null;
        try {
            i = await m.awaitMessageComponent({ filter: (i) => i.user.id === interaction.user.id, time: 300000 }) as RoleSelectMenuInteraction | ButtonInteraction;
        } catch (e) {
            closed = true;
            continue;
        }

        i.deferUpdate();
        if(i.isButton()) {
            switch(i.customId) {
                case "roleSave": {
                    const roles = rolesToChange.map((r) => interaction.guild?.roles.cache.get(r)!);
                    await interaction.editReply({ embeds: LoadingEmbed, components: [] });
                    const rolesToAdd: Role[] = [];
                    const rolesToRemove: Role[] = [];
                    for(const role of roles) {
                        if(!canEdit(role, interaction.member as GuildMember, interaction.guild?.members.me!)[1]) continue;
                        if(member.roles.cache.has(role.id)) {
                            rolesToRemove.push(role);
                        } else {
                            rolesToAdd.push(role);
                        }
                    }
                    await member.roles.add(rolesToAdd);
                    await member.roles.remove(rolesToRemove);
                    rolesToChange = [];
                    break;
                }
                case "roleDiscard": {
                    rolesToChange = [];
                    await interaction.editReply({ embeds: LoadingEmbed, components: [] });
                    break;
                }
            }
        } else {
            rolesToChange = i.values;
        }

    } while (!closed);

};

const check = (interaction: CommandInteraction, partial: boolean = false) => {
    const member = interaction.member as GuildMember;
    // Check if the user has manage_roles permission
    if (!member.permissions.has("ManageRoles")) return "You do not have the *Manage Roles* permission";
    if (partial) return true;
    if (!interaction.guild) return
    const me = interaction.guild.members.me!;
    // Check if Nucleus has permission to role
    if (!me.permissions.has("ManageRoles")) return "I do not have the *Manage Roles* permission";
    // Allow the owner to role anyone
    if (member.id === interaction.guild.ownerId) return true;
    // Allow role
    return true;
};

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