import { LoadingEmbed } from "./../../utils/defaultEmbeds.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 confirmationMessage from "../../utils/confirmationMessage.js";
import keyValueList from "../../utils/generateKeyValueList.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
import client from "../../utils/client.js";
import { areTicketsEnabled, create } from "../../actions/createModActionTicket.js";

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("mute")
        .setDescription("Mutes a member, stopping them from talking in the server")
        .addUserOption((option) => option.setName("user").setDescription("The user to mute").setRequired(true))
        .addIntegerOption((option) =>
            option
                .setName("days")
                .setDescription("The number of days to mute the user for | Default: 0")
                .setMinValue(0)
                .setMaxValue(27)
                .setRequired(false)
        )
        .addIntegerOption((option) =>
            option
                .setName("hours")
                .setDescription("The number of hours to mute the user for | Default: 0")
                .setMinValue(0)
                .setMaxValue(23)
                .setRequired(false)
        )
        .addIntegerOption((option) =>
            option
                .setName("minutes")
                .setDescription("The number of minutes to mute the user for | Default: 0")
                .setMinValue(0)
                .setMaxValue(59)
                .setRequired(false)
        )
        .addIntegerOption((option) =>
            option
                .setName("seconds")
                .setDescription("The number of seconds to mute the user for | Default: 0")
                .setMinValue(0)
                .setMaxValue(59)
                .setRequired(false)
        );

const callback = async (interaction: CommandInteraction): Promise<unknown> => {
    const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger;
    const user = interaction.options.getMember("user") as GuildMember;
    const time = {
        days: interaction.options.getInteger("days") ?? 0,
        hours: interaction.options.getInteger("hours") ?? 0,
        minutes: interaction.options.getInteger("minutes") ?? 0,
        seconds: interaction.options.getInteger("seconds") ?? 0
    };
    const config = await client.database.guilds.read(interaction.guild!.id);
    let serverSettingsDescription = config.moderation.mute.timeout ? "given a timeout" : "";
    if (config.moderation.mute.role)
        serverSettingsDescription +=
            (serverSettingsDescription ? " and " : "") + `given the <@&${config.moderation.mute.role}> role`;

    let muteTime = time.days * 24 * 60 * 60 + time.hours * 60 * 60 + time.minutes * 60 + time.seconds;
    if (muteTime === 0) {
        const m = (await interaction.reply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("PUNISH.MUTE.GREEN")
                    .setTitle("Mute")
                    .setDescription("How long should the user be muted")
                    .setStatus("Success")
            ],
            components: [
                new ActionRowBuilder().addComponents([
                    new Discord.ButtonBuilder().setCustomId("1m").setLabel("1 Minute").setStyle(ButtonStyle.Secondary),
                    new Discord.ButtonBuilder().setCustomId("10m").setLabel("10 Minutes").setStyle(ButtonStyle.Secondary),
                    new Discord.ButtonBuilder().setCustomId("30m").setLabel("30 Minutes").setStyle(ButtonStyle.Secondary),
                    new Discord.ButtonBuilder().setCustomId("1h").setLabel("1 Hour").setStyle(ButtonStyle.Secondary)
                ]),
                new ActionRowBuilder().addComponents([
                    new Discord.ButtonBuilder().setCustomId("6h").setLabel("6 Hours").setStyle(ButtonStyle.Secondary),
                    new Discord.ButtonBuilder().setCustomId("12h").setLabel("12 Hours").setStyle(ButtonStyle.Secondary),
                    new Discord.ButtonBuilder().setCustomId("1d").setLabel("1 Day").setStyle(ButtonStyle.Secondary),
                    new Discord.ButtonBuilder().setCustomId("1w").setLabel("1 Week").setStyle(ButtonStyle.Secondary)
                ]),
                new ActionRowBuilder().addComponents([
                    new Discord.ButtonBuilder()
                        .setCustomId("cancel")
                        .setLabel("Cancel")
                        .setStyle(ButtonStyle.Danger)
                        .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
                ])
            ],
            ephemeral: true,
            fetchReply: true
        })) as Message;
        let component;
        try {
            component = await m.awaitMessageComponent({
                filter: (m) => m.user.id === interaction.user.id,
                time: 300000
            });
        } catch {
            return;
        }
        component.deferUpdate();
        if (component.customId === "cancel")
            return interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("PUNISH.MUTE.RED")
                        .setTitle("Mute")
                        .setDescription("Mute cancelled")
                        .setStatus("Danger")
                ]
            });
        switch (component.customId) {
            case "1m": {
                muteTime = 60;
                break;
            }
            case "10m": {
                muteTime = 60 * 10;
                break;
            }
            case "30m": {
                muteTime = 60 * 30;
                break;
            }
            case "1h": {
                muteTime = 60 * 60;
                break;
            }
            case "6h": {
                muteTime = 60 * 60 * 6;
                break;
            }
            case "12h": {
                muteTime = 60 * 60 * 12;
                break;
            }
            case "1d": {
                muteTime = 60 * 60 * 24;
                break;
            }
            case "1w": {
                muteTime = 60 * 60 * 24 * 7;
                break;
            }
        }
    } else {
        await interaction.reply({
            embeds: LoadingEmbed,
            ephemeral: true,
            fetchReply: true
        });
    }
    // TODO:[Modals] Replace this with a modal
    let reason: string | null = null;
    let notify = true;
    let createAppealTicket = false;
    let confirmation;
    let timedOut = false;
    let success = false;
    do {
        confirmation = await new confirmationMessage(interaction)
            .setEmoji("PUNISH.MUTE.RED")
            .setTitle("Mute")
            .setDescription(
                keyValueList({
                    user: renderUser(user.user),
                    time: `${humanizeDuration(muteTime * 1000, {
                        round: true
                    })}`,
                    reason: reason ? "\n> " + (reason).replaceAll("\n", "\n> ") : "*No reason provided*"
                }) +
                    "The user will be " +
                    serverSettingsDescription +
                    "\n" +
                    `The user **will${notify ? "" : " not"}** be notified\n\n` +
                    `Are you sure you want to mute <@!${user.id}>?`
            )
            .setColor("Danger")
            .addCustomBoolean(
                "appeal",
                "Create appeal ticket",
                !(await areTicketsEnabled(interaction.guild!.id)),
                async () =>
                    await create(interaction.guild!, interaction.options.getUser("user")!, interaction.user, reason),
                "An appeal ticket will be created when Confirm is clicked",
                "CONTROL.TICKET",
                createAppealTicket
            )
            .addCustomBoolean(
                "notify",
                "Notify user",
                false,
                undefined,
                null,
                "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
                notify
            )
            .addReasonButton(reason ?? "")
            .send(true);
        reason = reason ?? "";
        if (confirmation.cancelled) timedOut = true;
        if (confirmation.success) success = true;
        if (confirmation.newReason) reason = confirmation.newReason;
        if (confirmation.components) {
            notify = confirmation.components["notify"]!.active;
            createAppealTicket = confirmation.components["appeal"]!.active;
        }
    } while (!timedOut && !success)
    if (timedOut) return;
    let dmd = false;
    let dm;
    if (confirmation.success) {
        try {
            if (notify) {
                dm = await user.send({
                    embeds: [
                        new EmojiEmbed()
                            .setEmoji("PUNISH.MUTE.RED")
                            .setTitle("Muted")
                            .setDescription(
                                `You have been muted in ${interaction.guild!.name}` +
                                    (reason
                                        ? ` for:\n> ${reason}`
                                        : ".\n\n" +
                                        `You will be unmuted at: <t:${
                                            Math.round(new Date().getTime() / 1000) + muteTime
                                        }:D> at <t:${Math.round(new Date().getTime() / 1000) + muteTime}:T> (<t:${
                                            Math.round(new Date().getTime() / 1000) + muteTime
                                        }:R>)`) +
                                    (confirmation.components!["appeal"]!.response
                                        ? `You can appeal this here: <#${confirmation.components!["appeal"]!.response}>`
                                        : "")
                            )
                            .setStatus("Danger")
                    ],
                    components: [
                        new ActionRowBuilder().addComponents(
                            config.moderation.mute.text
                                ? [
                                    new ButtonBuilder()
                                        .setStyle(ButtonStyle.Link)
                                        .setLabel(config.moderation.mute.text)
                                        .setURL(config.moderation.mute.link)
                                ]
                                : []
                        )
                    ]
                });
                dmd = true;
            }
        } catch {
            dmd = false;
        }
        const member = user;
        let errors = 0;
        try {
            if (config.moderation.mute.timeout) {
                await member.timeout(muteTime * 1000, reason || "No reason provided");
                if (config.moderation.mute.role !== null) {
                    await member.roles.add(config.moderation.mute.role);
                    await client.database.eventScheduler.schedule("naturalUnmute", new Date().getTime() + muteTime * 1000, {
                        guild: interaction.guild!.id,
                        user: user.id,
                        expires: new Date().getTime() + muteTime * 1000
                    });
                }
            }
        } catch {
            errors++;
        }
        try {
            if (config.moderation.mute.role !== null) {
                await member.roles.add(config.moderation.mute.role);
                await client.database.eventScheduler.schedule("unmuteRole", new Date().getTime() + muteTime * 1000, {
                    guild: interaction.guild!.id,
                    user: user.id,
                    role: config.moderation.mute.role
                });
            }
        } catch (e) {
            console.log(e);
            errors++;
        }
        if (errors === 2) {
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("PUNISH.MUTE.RED")
                        .setTitle("Mute")
                        .setDescription("Something went wrong and the user was not muted")
                        .setStatus("Danger")
                ],
                components: []
            }); // TODO: make this clearer
            if (dmd && dm) await dm.delete();
            return;
        }
        await client.database.history.create("mute", interaction.guild!.id, member.user, interaction.user, reason);
        const failed = !dmd && notify;
        await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
                    .setTitle("Mute")
                    .setDescription(
                        "The member was muted" +
                            (failed ? ", but could not be notified" : "") +
                            (confirmation.components!["appeal"]!.response
                                ? ` and an appeal ticket was opened in <#${confirmation.components!["appeal"]!.response}>`
                                : "")
                    )
                    .setStatus(failed ? "Warning" : "Success")
            ],
            components: []
        });
        const data = {
            meta: {
                type: "memberMute",
                displayName: "Member Muted",
                calculateType: "guildMemberPunish",
                color: NucleusColors.yellow,
                emoji: "PUNISH.WARN.YELLOW",
                timestamp: new Date().getTime()
            },
            list: {
                memberId: entry(member.user.id, `\`${member.user.id}\``),
                name: entry(member.user.id, renderUser(member.user)),
                mutedUntil: entry(
                    new Date().getTime() + muteTime * 1000,
                    renderDelta(new Date().getTime() + muteTime * 1000)
                ),
                muted: entry(new Date().getTime(), renderDelta(new Date().getTime() - 1000)),
                mutedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user)),
                reason: entry(reason, reason ? reason : "*No reason provided*")
            },
            hidden: {
                guild: interaction.guild!.id
            }
        };
        log(data);
    } else {
        await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("PUNISH.BAN.GREEN")
                    .setTitle("Softban")
                    .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;
    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 muting the owner
    if (member.id === interaction.guild!.ownerId) throw new Error("You cannot mute the owner of the server");
    // Check if Nucleus can mute the member
    if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
    // Check if Nucleus has permission to mute
    if (!me.permissions.has("MODERATE_MEMBERS")) throw new Error("I do not have the *Moderate Members* permission");
    // Do not allow muting Nucleus
    if (member.id === me.id) throw new Error("I cannot mute myself");
    // Allow the owner to mute 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 mute
    return true;
};

export { command, callback, check };
