import Discord, {
    CommandInteraction,
    GuildChannel,
    GuildMember,
    TextChannel,
    ButtonStyle,
    ButtonBuilder,
    Message
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js";
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> => {
    if (!interaction.guild) return;
    const user = interaction.options.getMember("user") as GuildMember | null;
    const channel = interaction.channel as GuildChannel;
    if (!channel.isTextBased()) {
        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.get("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<ButtonBuilder>().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<ButtonBuilder>().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<ButtonBuilder>().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: (i) => i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.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: Discord.Message[] = [];
            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)).map((m) => m as Discord.Message);
            });
            deleted = deleted.concat(messages);
        }
        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.user,
                interaction.user,
                (interaction.options.get("reason")?.value as string | null) ?? "*No reason provided*",
                null,
                null,
                deleted.length.toString()
            );
        }
        const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
        const data = {
            meta: {
                type: "channelPurge",
                displayName: "Channel Purged",
                calculateType: "messageDelete",
                color: NucleusColors.red,
                emoji: "CHANNEL.PURGE.RED",
                timestamp: Date.now()
            },
            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! as GuildChannel)),
                messagesCleared: entry(deleted.length.toString(), deleted.length.toString())
            },
            hidden: {
                guild: interaction.guild.id
            }
        };
        log(data);
        const newOut = await client.database.transcripts.createTranscript(
            "purge",
            deleted,
            interaction,
            interaction.member as GuildMember
        );
        const transcript = client.database.transcripts.toHumanReadable(newOut);
        const attachmentObject = {
            attachment: Buffer.from(transcript),
            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<ButtonBuilder>().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: (i) =>
                    i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id && i.id === m.id,
                time: 300000
            });
        } catch {
            return;
        }
        if (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.get("amount")?.value as number).toString(),
                    reason: `\n> ${
                        interaction.options.get("reason")?.value
                            ? interaction.options.get("reason")?.value
                            : "*No reason provided*"
                    }`
                })
            )
            .setColor("Danger")
            .setFailedMessage("No changes were made", "Success", "CHANNEL.PURGE.GREEN")
            .send();
        if (confirmation.cancelled || !confirmation.success) return;
        let messages;
        try {
            if (!user) {
                const toDelete = await (interaction.channel as TextChannel).messages.fetch({
                    limit: interaction.options.get("amount")?.value as number
                });
                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.get("amount")?.value as number);
                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 (!messages) {
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("CHANNEL.PURGE.RED")
                        .setTitle("Purge")
                        .setDescription("No messages could be deleted")
                        .setStatus("Danger")
                ],
                components: []
            });
            return;
        }
        if (user) {
            await client.database.history.create(
                "purge",
                interaction.guild.id,
                user.user,
                interaction.user,
                (interaction.options.get("reason")?.value as string | null) ?? "*No reason provided*",
                null,
                null,
                messages.size.toString()
            );
        }
        const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
        const data = {
            meta: {
                type: "channelPurge",
                displayName: "Channel Purged",
                calculateType: "messageDelete",
                color: NucleusColors.red,
                emoji: "CHANNEL.PURGE.RED",
                timestamp: Date.now()
            },
            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! as GuildChannel)),
                messagesCleared: entry(messages.size.toString(), messages.size.toString())
            },
            hidden: {
                guild: interaction.guild.id
            }
        };
        log(data);
        const messageArray: Message[] = messages
            .filter(
                (message) =>
                    !message!.components.some((component) =>
                        component.components.some((child) => child.customId?.includes("transcript") ?? false)
                    )
            )
            .map((message) => message as Message);
        const newOut = await client.database.transcripts.createTranscript(
            "purge",
            messageArray,
            interaction,
            interaction.member as GuildMember
        );

        const [code, key, iv] = await client.database.transcripts.create(newOut);

        await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("CHANNEL.PURGE.GREEN")
                    .setTitle("Purge")
                    .setDescription("Messages cleared")
                    .setStatus("Success")
            ],
            components: [
                new Discord.ActionRowBuilder<ButtonBuilder>().addComponents([
                    new ButtonBuilder()
                        .setLabel("View")
                        .setStyle(ButtonStyle.Link)
                        .setURL(`https://clicks.codes/nucleus/transcript/${code}?key=${key}&iv=${iv}`)
                        .setDisabled(!code)
                ])
            ]
        });
    }
};

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

export { command, callback, check };
export const metadata = {
    longDescription:
        "Deletes a specified amount of messages from a channel, optionally from a specific user. Without an amount, you can repeatedly choose a number of messages to delete.",
    premiumOnly: true
};
