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

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("purge")
        .setDescription("Bulk deletes messages in a channel")
        .addIntegerOption((option) =>
            option
                .setName("amount")
                .setDescription("The amount of messages to delete")
                .setRequired(false)
                .setMinValue(1)
                .setMaxValue(100)
        )
        .addUserOption((option) =>
            option.setName("user").setDescription("The user to purge messages from").setRequired(false)
        )
        .addStringOption((option) =>
            option.setName("reason").setDescription("The reason for the purge").setRequired(false)
        );

const callback = async (interaction: CommandInteraction): Promise<unknown> => {
    const user = (interaction.options.getMember("user") as GuildMember) ?? null;
    const channel = interaction.channel as GuildChannel;
    if (
        !["GUILD_TEXT", "GUILD_NEWS", "GUILD_NEWS_THREAD", "GUILD_PUBLIC_THREAD", "GUILD_PRIVATE_THREAD"].includes(
            channel.type.toString()
        )
    ) {
        return await interaction.reply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("CHANNEL.PURGE.RED")
                    .setTitle("Purge")
                    .setDescription("You cannot purge this channel")
                    .setStatus("Danger")
            ],
            components: [],
            ephemeral: true
        });
    }
    // TODO:[Modals] Replace this with a modal
    if (!interaction.options.getInteger("amount")) {
        await interaction.reply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("CHANNEL.PURGE.RED")
                    .setTitle("Purge")
                    .setDescription("Select how many messages to delete")
                    .setStatus("Danger")
            ],
            components: [],
            ephemeral: true,
            fetchReply: true
        });
        let deleted = [] as Discord.Message[];
        let timedOut = false;
        let amountSelected = false;
        while (!timedOut && !amountSelected) {
            const m = (await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("CHANNEL.PURGE.RED")
                        .setTitle("Purge")
                        .setDescription(
                            "Select how many messages to delete. You can continue clicking until all messages are cleared."
                        )
                        .setStatus("Danger")
                ],
                components: [
                    new Discord.ActionRowBuilder().addComponents([
                        new Discord.ButtonBuilder().setCustomId("1").setLabel("1").setStyle(ButtonStyle.Secondary),
                        new Discord.ButtonBuilder().setCustomId("3").setLabel("3").setStyle(ButtonStyle.Secondary),
                        new Discord.ButtonBuilder().setCustomId("5").setLabel("5").setStyle(ButtonStyle.Secondary)
                    ]),
                    new Discord.ActionRowBuilder().addComponents([
                        new Discord.ButtonBuilder().setCustomId("10").setLabel("10").setStyle(ButtonStyle.Secondary),
                        new Discord.ButtonBuilder().setCustomId("25").setLabel("25").setStyle(ButtonStyle.Secondary),
                        new Discord.ButtonBuilder().setCustomId("50").setLabel("50").setStyle(ButtonStyle.Secondary)
                    ]),
                    new Discord.ActionRowBuilder().addComponents([
                        new Discord.ButtonBuilder()
                            .setCustomId("done")
                            .setLabel("Done")
                            .setStyle(ButtonStyle.Success)
                            .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
                    ])
                ]
            })) as Discord.Message;
            let component;
            try {
                component = m.awaitMessageComponent({
                    filter: (m) => m.user.id === interaction.user.id,
                    time: 300000
                });
            } catch (e) {
                timedOut = true;
                continue;
            }
            (await component).deferUpdate();
            if ((await component).customId === "done") {
                amountSelected = true;
                continue;
            }
            const amount = parseInt((await component).customId);

            let messages;
            await (interaction.channel as TextChannel).messages.fetch({ limit: amount }).then(async (ms) => {
                if (user) {
                    ms = ms.filter((m) => m.author.id === user.id);
                }
                messages = await (channel as TextChannel).bulkDelete(ms, true);
            });
            if (messages) {
                deleted = deleted.concat(messages.map((m) => m));
            }
        }
        if (deleted.length === 0)
            return await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("CHANNEL.PURGE.RED")
                        .setTitle("Purge")
                        .setDescription("No messages were deleted")
                        .setStatus("Danger")
                ],
                components: []
            });
        if (user) {
            await client.database.history.create(
                "purge",
                interaction.guild.id,
                user,
                interaction.options.getString("reason"),
                null,
                null,
                deleted.length
            );
        }
        const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
        const data = {
            meta: {
                type: "channelPurge",
                displayName: "Channel Purged",
                calculateType: "messageDelete",
                color: NucleusColors.red,
                emoji: "PUNISH.BAN.RED",
                timestamp: new Date().getTime()
            },
            list: {
                memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
                purgedBy: entry(interaction.user.id, renderUser(interaction.user)),
                channel: entry(interaction.channel.id, renderChannel(interaction.channel)),
                messagesCleared: entry(deleted.length, deleted.length)
            },
            hidden: {
                guild: interaction.guild.id
            }
        };
        log(data);
        let out = "";
        deleted.reverse().forEach((message) => {
            out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(
                message.createdTimestamp
            ).toISOString()}]\n`;
            const lines = message.content.split("\n");
            lines.forEach((line) => {
                out += `> ${line}\n`;
            });
            out += "\n\n";
        });
        const attachmentObject = {
            attachment: Buffer.from(out),
            name: `purge-${channel.id}-${Date.now()}.txt`,
            description: "Purge log"
        };
        const m = (await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("CHANNEL.PURGE.GREEN")
                    .setTitle("Purge")
                    .setDescription("Messages cleared")
                    .setStatus("Success")
            ],
            components: [
                new Discord.ActionRowBuilder().addComponents([
                    new Discord.ButtonBuilder()
                        .setCustomId("download")
                        .setLabel("Download transcript")
                        .setStyle(ButtonStyle.Success)
                        .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
                ])
            ]
        })) as Discord.Message;
        let component;
        try {
            component = await m.awaitMessageComponent({
                filter: (m) => m.user.id === interaction.user.id,
                time: 300000
            });
        } catch {
            return;
        }
        if (component && component.customId === "download") {
            interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("CHANNEL.PURGE.GREEN")
                        .setTitle("Purge")
                        .setDescription("Uploaded")
                        .setStatus("Success")
                ],
                components: [],
                files: [attachmentObject]
            });
        } else {
            interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("CHANNEL.PURGE.GREEN")
                        .setTitle("Purge")
                        .setDescription("Messages cleared")
                        .setStatus("Success")
                ],
                components: []
            });
        }
        return;
    } else {
        const confirmation = await new confirmationMessage(interaction)
            .setEmoji("CHANNEL.PURGE.RED")
            .setTitle("Purge")
            .setDescription(
                keyValueList({
                    channel: `<#${channel.id}>`,
                    amount: interaction.options.getInteger("amount").toString(),
                    reason: `\n> ${
                        interaction.options.getString("reason")
                            ? interaction.options.getString("reason")
                            : "*No reason provided*"
                    }`
                })
            )
            .setColor("Danger")
            .send();
        if (confirmation.cancelled) return;
        if (confirmation.success) {
            let messages;
            try {
                if (!user) {
                    const toDelete = await (interaction.channel as TextChannel).messages.fetch({
                        limit: interaction.options.getInteger("amount")
                    });
                    messages = await (channel as TextChannel).bulkDelete(toDelete, true);
                } else {
                    const toDelete = (
                        await (
                            await (interaction.channel as TextChannel).messages.fetch({
                                limit: 100
                            })
                        ).filter((m) => m.author.id === user.id)
                    ).first(interaction.options.getInteger("amount"));
                    messages = await (channel as TextChannel).bulkDelete(toDelete, true);
                }
            } catch (e) {
                await interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setEmoji("CHANNEL.PURGE.RED")
                            .setTitle("Purge")
                            .setDescription("Something went wrong and no messages were deleted")
                            .setStatus("Danger")
                    ],
                    components: []
                });
            }
            if (user) {
                await client.database.history.create(
                    "purge",
                    interaction.guild.id,
                    user,
                    interaction.options.getString("reason"),
                    null,
                    null,
                    messages.size
                );
            }
            const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
            const data = {
                meta: {
                    type: "channelPurge",
                    displayName: "Channel Purged",
                    calculateType: "messageDelete",
                    color: NucleusColors.red,
                    emoji: "PUNISH.BAN.RED",
                    timestamp: new Date().getTime()
                },
                list: {
                    memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
                    purgedBy: entry(interaction.user.id, renderUser(interaction.user)),
                    channel: entry(interaction.channel.id, renderChannel(interaction.channel)),
                    messagesCleared: entry(messages.size, messages.size)
                },
                hidden: {
                    guild: interaction.guild.id
                }
            };
            log(data);
            let out = "";
            messages.reverse().forEach((message) => {
                out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(
                    message.createdTimestamp
                ).toISOString()}]\n`;
                const lines = message.content.split("\n");
                lines.forEach((line) => {
                    out += `> ${line}\n`;
                });
                out += "\n\n";
            });
            const attachmentObject = {
                attachment: Buffer.from(out),
                name: `purge-${channel.id}-${Date.now()}.txt`,
                description: "Purge log"
            };
            const m = (await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("CHANNEL.PURGE.GREEN")
                        .setTitle("Purge")
                        .setDescription("Messages cleared")
                        .setStatus("Success")
                ],
                components: [
                    new Discord.ActionRowBuilder().addComponents([
                        new Discord.ButtonBuilder()
                            .setCustomId("download")
                            .setLabel("Download transcript")
                            .setStyle(ButtonStyle.Success)
                            .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
                    ])
                ]
            })) as Discord.Message;
            let component;
            try {
                component = await m.awaitMessageComponent({
                    filter: (m) => m.user.id === interaction.user.id,
                    time: 300000
                });
            } catch {
                return;
            }
            if (component && component.customId === "download") {
                interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setEmoji("CHANNEL.PURGE.GREEN")
                            .setTitle("Purge")
                            .setDescription("Transcript uploaded above")
                            .setStatus("Success")
                    ],
                    components: [],
                    files: [attachmentObject]
                });
            } else {
                interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setEmoji("CHANNEL.PURGE.GREEN")
                            .setTitle("Purge")
                            .setDescription("Messages cleared")
                            .setStatus("Success")
                    ],
                    components: []
                });
            }
        } else {
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("CHANNEL.PURGE.GREEN")
                        .setTitle("Purge")
                        .setDescription("No changes were made")
                        .setStatus("Success")
                ],
                components: []
            });
        }
    }
};

const check = (interaction: CommandInteraction) => {
    const member = interaction.member as GuildMember;
    const me = interaction.guild.me!;
    // Check if nucleus has the manage_messages permission
    if (!me.permissions.has("MANAGE_MESSAGES")) throw new Error("I do not have the *Manage Messages* permission");
    // Allow the owner to purge
    if (member.id === interaction.guild.ownerId) return true;
    // Check if the user has manage_messages permission
    if (!member.permissions.has("MANAGE_MESSAGES")) throw new Error("You do not have the *Manage Messages* permission");
    // Allow purge
    return true;
};

export { command, callback, check };
