import Discord, { CommandInteraction, GuildChannel, GuildMember, TextChannel } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import getEmojiByName from "../../utils/getEmojiByName.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(50))
    .addChannelOption(option => option.setName("channel").setDescription("The channel to purge messages from").setRequired(false))
    .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) => {
    let user = interaction.options.getMember("user") as GuildMember ?? null
    let channel = (interaction.options.getChannel("channel") as GuildChannel) ?? interaction.channel
    let thischannel
    if ((interaction.options.getChannel("channel") as GuildChannel) == null) {
        thischannel = true
    } else {
        thischannel = (interaction.options.getChannel("channel") as GuildChannel).id == interaction.channel.id
    }
    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[]
        while (true) {
            let 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.MessageActionRow().addComponents([
                        new Discord.MessageButton()
                            .setCustomId("1")
                            .setLabel("1")
                            .setStyle("SECONDARY"),
                        new Discord.MessageButton()
                            .setCustomId("3")
                            .setLabel("3")
                            .setStyle("SECONDARY"),
                        new Discord.MessageButton()
                            .setCustomId("5")
                            .setLabel("5")
                            .setStyle("SECONDARY")
                        ]),
                        new Discord.MessageActionRow().addComponents([
                        new Discord.MessageButton()
                            .setCustomId("10")
                            .setLabel("10")
                            .setStyle("SECONDARY"),
                        new Discord.MessageButton()
                            .setCustomId("25")
                            .setLabel("25")
                            .setStyle("SECONDARY"),
                        new Discord.MessageButton()
                            .setCustomId("50")
                            .setLabel("50")
                            .setStyle("SECONDARY")
                    ]),
                    new Discord.MessageActionRow().addComponents([
                        new Discord.MessageButton()
                            .setCustomId("done")
                            .setLabel("Done")
                            .setStyle("SUCCESS")
                            .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
                    ])
                ]
            })
            let component;
            try {
                component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 2.5 * 60 * 1000});
            } catch (e) { break; }
            component.deferUpdate();
            if (component.customId === "done") break;
            let amount;
            try { amount = parseInt(component.customId); } catch { break; }
            let messages;
            (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);
            })
            deleted = deleted.concat(messages.map(m => m)) // TODO: .values doesnt work so using .map
            // TODO: Support for users
        }
        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: []
        })
        let attachmentObject;
        try {
            let out = ""
            deleted.reverse().forEach(message => {
                out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(message.createdTimestamp).toISOString()}]\n`
                let lines = message.content.split("\n")
                lines.forEach(line => {out += `> ${line}\n`})
                out += `\n\n`
            })
            attachmentObject = {
                attachment: Buffer.from(out),
                name: `purge-${channel.id}-${Date.now()}.txt`,
                description: "Purge log"
            }
        } catch {}
        let m = await interaction.editReply({embeds: [new EmojiEmbed()
            .setEmoji(`CHANNEL.PURGE.GREEN`)
            .setTitle(`Purge`)
            .setDescription("Messages cleared")
            .setStatus("Success")
        ], components: [new Discord.MessageActionRow().addComponents([
            new Discord.MessageButton()
                .setCustomId("download")
                .setLabel("Download transcript")
                .setStyle("SUCCESS")
                .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
        ])]})
        let component;
        try {
            component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 2.5 * 60 * 1000});
        } catch {}
        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 {
        if (await new confirmationMessage(interaction)
            .setEmoji("CHANNEL.PURGE.RED")
            .setTitle("Purge")
            .setDescription(keyValueList({
                "channel": `<#${channel.id}> (${(channel as GuildChannel).name})` + (thischannel ? " [This channel]" : ""),
                "amount": interaction.options.getInteger("amount").toString(),
                "reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
            }))
            .setColor("Danger")
    //        pluralize("day", interaction.options.getInteger("amount"))
    //        const pluralize = (word: string, count: number) => { return count === 1 ? word : word + "s" }
        .send()) {
            let messages;
            try {
                (interaction.channel as TextChannel).messages.fetch({limit: interaction.options.getInteger("amount")}).then(async (ms) => {
                    if (user) {
                        ms = ms.filter(m => m.author.id === user.id)
                    }
                    messages = await (channel as TextChannel).bulkDelete(ms, true);
                }) // TODO: fix for purge amount by user, not just checking x
            } catch(e) {
                console.log(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: []})
            }
            let attachmentObject;
            try {
                let out = ""
                messages.reverse().forEach(message => {
                    out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(message.createdTimestamp).toISOString()}]\n`
                    let lines = message.content.split("\n")
                    lines.forEach(line => {out += `> ${line}\n`})
                    out += `\n\n`
                })
                attachmentObject = {
                    attachment: Buffer.from(out),
                    name: `purge-${channel.id}-${Date.now()}.txt`,
                    description: `Purge log`
                }
            } catch {}
            let m = await interaction.editReply({embeds: [new EmojiEmbed()
                .setEmoji(`CHANNEL.PURGE.GREEN`)
                .setTitle(`Purge`)
                .setDescription("Messages cleared")
                .setStatus("Success")
            ], components: [new Discord.MessageActionRow().addComponents([
                new Discord.MessageButton()
                    .setCustomId("download")
                    .setLabel("Download transcript")
                    .setStyle("SUCCESS")
                    .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
            ])]})
            let component;
            try {
                component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 2.5 * 60 * 1000});
            } catch {}
            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: []})
            }
        } 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, defaultCheck: WrappedCheck) => {
    // Allow the owner to purge
    if ((interaction.member as GuildMember).id == interaction.guild.ownerId) return true
    // Check if the user has manage_messages permission
    if (! (interaction.member as GuildMember).permissions.has("MANAGE_MESSAGES")) throw "You do not have the `manage_messages` permission";
    // Check if nucleus has the manage_messages permission
    if (! interaction.guild.me.permissions.has("MANAGE_MESSAGES")) throw "I do not have the `manage_messages` permission";
    // Allow warn
    return true
}

export { command, callback, check };