import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
import Discord, { CommandInteraction, GuildMember, Message, MessageActionRow, MessageButton } from "discord.js";
import { 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";
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 MessageActionRow().addComponents([
                    new Discord.MessageButton().setCustomId("1m").setLabel("1 Minute").setStyle("SECONDARY"),
                    new Discord.MessageButton().setCustomId("10m").setLabel("10 Minutes").setStyle("SECONDARY"),
                    new Discord.MessageButton().setCustomId("30m").setLabel("30 Minutes").setStyle("SECONDARY"),
                    new Discord.MessageButton().setCustomId("1h").setLabel("1 Hour").setStyle("SECONDARY")
                ]),
                new MessageActionRow().addComponents([
                    new Discord.MessageButton().setCustomId("6h").setLabel("6 Hours").setStyle("SECONDARY"),
                    new Discord.MessageButton().setCustomId("12h").setLabel("12 Hours").setStyle("SECONDARY"),
                    new Discord.MessageButton().setCustomId("1d").setLabel("1 Day").setStyle("SECONDARY"),
                    new Discord.MessageButton().setCustomId("1w").setLabel("1 Week").setStyle("SECONDARY")
                ]),
                new MessageActionRow().addComponents([
                    new Discord.MessageButton()
                        .setCustomId("cancel")
                        .setLabel("Cancel")
                        .setStyle("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 = null;
    let notify = true;
    let createAppealTicket = false;
    let confirmation;
    let timedOut = false;
    let success = false;
    while (!timedOut && !success) {
        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,
                null,
                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;
        }
    }
    if (timedOut) return;
    let dmd = false;
    let dm;
    const config = await client.database.guilds.read(interaction.guild.id);
    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 MessageActionRow().addComponents(
                        config.moderation.mute.text
                            ? [
                                  new MessageButton()
                                      .setStyle("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) 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);
};

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 ? member.roles.highest.position : 0;
    const mePos = me.roles ? me.roles.highest.position : 0;
    const applyPos = apply.roles ? 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 };
