import { CommandInteraction, GuildMember } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import client from "../../utils/client.js";

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("unmute")
        .setDescription("Unmutes a user")
        .addUserOption((option) => option.setName("user").setDescription("The user to unmute").setRequired(true));

const callback = async (interaction: CommandInteraction): Promise<unknown> => {
    const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger;
    // TODO:[Modals] Replace this with a modal
    let reason = null;
    let notify = false;
    let confirmation;
    let success = false;
    while (!success) {
        confirmation = await new confirmationMessage(interaction)
            .setEmoji("PUNISH.MUTE.RED")
            .setTitle("Unmute")
            .setDescription(
                keyValueList({
                    user: renderUser(interaction.options.getUser("user")),
                    reason: `\n> ${reason ? reason : "*No reason provided*"}`
                }) +
                    `The user **will${notify ? "" : " not"}** be notified\n\n` +
                    `Are you sure you want to unmute <@!${(interaction.options.getMember("user") as GuildMember).id}>?`
            )
            .setColor("Danger")
            .addReasonButton(reason ?? "")
            .send(reason !== null);
        if (confirmation.success) success = true;
        else if (confirmation.newReason) reason = confirmation.newReason;
        else if (confirmation.components) {
            notify = confirmation.components.notify.active;
        }
    }
    if (confirmation.cancelled) return;
    if (confirmation.success) {
        let dmd = false;
        let dm;
        try {
            if (notify) {
                dm = await (interaction.options.getMember("user") as GuildMember).send({
                    embeds: [
                        new EmojiEmbed()
                            .setEmoji("PUNISH.MUTE.GREEN")
                            .setTitle("Unmuted")
                            .setDescription(
                                `You have been unmuted in ${interaction.guild.name}` +
                                    (reason ? ` for:\n> ${reason}` : " with no reason provided.")
                            )
                            .setStatus("Success")
                    ]
                });
                dmd = true;
            }
        } catch {
            dmd = false;
        }
        const member = interaction.options.getMember("user") as GuildMember;
        try {
            member.timeout(0, reason ?? "No reason provided");
        } catch {
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("PUNISH.MUTE.RED")
                        .setTitle("Unmute")
                        .setDescription("Something went wrong and the user was not unmuted")
                        .setStatus("Danger")
                ],
                components: []
            });
            if (dmd) await dm.delete();
            return;
        }
        await client.database.history.create(
            "unmute",
            interaction.guild.id,
            (interaction.options.getMember("user") as GuildMember).user,
            interaction.user,
            reason
        );
        const data = {
            meta: {
                type: "memberUnmute",
                displayName: "Unmuted",
                calculateType: "guildMemberPunish",
                color: NucleusColors.green,
                emoji: "PUNISH.MUTE.GREEN",
                timestamp: new Date().getTime()
            },
            list: {
                memberId: entry(member.user.id, `\`${member.user.id}\``),
                name: entry(member.user.id, renderUser(member.user)),
                unmuted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
                unmutedBy: entry(interaction.user.id, renderUser(interaction.user))
            },
            hidden: {
                guild: interaction.guild.id
            }
        };
        log(data);
        const failed = !dmd && notify;
        await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
                    .setTitle("Unmute")
                    .setDescription("The member was unmuted" + (failed ? ", but could not be notified" : ""))
                    .setStatus(failed ? "Warning" : "Success")
            ],
            components: []
        });
    } else {
        await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("PUNISH.MUTE.GREEN")
                    .setTitle("Unmute")
                    .setDescription("No changes were made")
                    .setStatus("Success")
            ],
            components: []
        });
    }
};

const check = (interaction: CommandInteraction) => {
    const member = interaction.member as GuildMember;
    const me = interaction.guild.me!;
    const apply = interaction.options.getMember("user") as GuildMember;
    if (member === null || me === null || apply === null) throw new Error("That member is not in the server");
    const memberPos = member.roles.cache.size > 1 ? member.roles.highest.position : 0;
    const mePos = me.roles.cache.size > 1 ? me.roles.highest.position : 0;
    const applyPos = apply.roles.cache.size > 1 ? apply.roles.highest.position : 0;
    // Do not allow unmuting the owner
    if (member.id === interaction.guild.ownerId) throw new Error("You cannot unmute the owner of the server");
    // Check if Nucleus can unmute the member
    if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
    // Check if Nucleus has permission to unmute
    if (!me.permissions.has("MODERATE_MEMBERS")) throw new Error("I do not have the *Moderate Members* permission");
    // Allow the owner to unmute anyone
    if (member.id === interaction.guild.ownerId) return true;
    // Check if the user has moderate_members permission
    if (!member.permissions.has("MODERATE_MEMBERS"))
        throw new Error("You do not have the *Moderate Members* permission");
    // Check if the user is below on the role list
    if (!(memberPos > applyPos)) throw new Error("You do not have a role higher than that member");
    // Allow unmute
    return true;
};

export { command, callback, check };
