import {
    CommandInteraction,
    GuildMember,
    Message,
    ActionRowBuilder,
    ButtonBuilder,
    MessageComponentInteraction,
    TextChannel,
    ButtonStyle,
    User,
    ThreadChannel
} from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import client from "../utils/client.js";
import { messageException } from "../utils/createTemporaryStorage.js";

const noTopic = new EmojiEmbed()
    .setTitle("User not found")
    .setDescription("There is no user associated with this ticket.")
    .setStatus("Danger")
    .setEmoji("CONTROL.BLOCKCROSS");

export default async function (interaction: CommandInteraction | MessageComponentInteraction) {
    if (interaction.channel === null) return;
    if (!(interaction.channel instanceof TextChannel || interaction.channel instanceof ThreadChannel)) return;
    const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;

    let messages: Message[] = [];
    let deletedCount: number;

    do {
        const fetched = await (interaction.channel as TextChannel).messages.fetch({ limit: 100 });
        const deleted = await (interaction.channel as TextChannel).bulkDelete(fetched, true);
        deletedCount = deleted.size;
        messages = messages.concat(Array.from(deleted.values() as Iterable<Message>));
        if (messages.length === 1) messageException(interaction.guild!.id, interaction.channel.id, messages[0]!.id);
    } while (deletedCount === 100);
    messages = messages.filter(
        (message) =>
            !message.components.some((component) =>
                component.components.some((child) => child.customId?.includes("transcript") ?? false)
            )
    );

    let topic;
    let member: GuildMember = interaction.guild?.members.me!;
    if (interaction.channel instanceof TextChannel) {
        topic = interaction.channel.topic;
        if (topic === null) return await interaction.reply({ embeds: [noTopic] });
        const mem = interaction.guild!.members.cache.get(topic.split(" ")[1]!);
        if (mem) member = mem;
    } else {
        topic = interaction.channel.name;
        const split = topic.split("-").map((p) => p.trim()) as [string, string, string];
        const mem = interaction.guild!.members.cache.get(split[1]);
        if (mem) member = mem;
    }

    const newOut = await client.database.transcripts.createTranscript(messages, interaction, member);

    const [code, key, iv] = await client.database.transcripts.create(newOut);
    if (!code)
        return await interaction.reply({
            embeds: [
                new EmojiEmbed()
                    .setTitle("Error")
                    .setDescription("An error occurred while creating the transcript.")
                    .setStatus("Danger")
                    .setEmoji("CONTROL.BLOCKCROSS")
            ]
        });
    const guildConfig = await client.database.guilds.read(interaction.guild!.id);
    const m: Message = (await interaction.reply({
        embeds: [
            new EmojiEmbed()
                .setTitle("Transcript")
                .setDescription(
                    "You can view the transcript using the link below. You can save the link for later" +
                        (guildConfig.logging.logs.channel
                            ? ` or find it in <#${guildConfig.logging.logs.channel}> once you press delete below. After this the channel will be deleted.`
                            : ". It will be automatically deleted after 30 days if a logging channel is not set.")
                )
                .setStatus("Success")
                .setEmoji("CONTROL.DOWNLOAD")
        ],
        components: [
            new ActionRowBuilder<ButtonBuilder>().addComponents([
                new ButtonBuilder()
                    .setLabel("View")
                    .setStyle(ButtonStyle.Link)
                    .setURL(`https://testing.coded.codes/nucleus/transcript/${code}?key=${key}&iv=${iv}`),
                new ButtonBuilder()
                    .setLabel("Delete")
                    .setStyle(ButtonStyle.Danger)
                    .setCustomId("close")
                    .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
            ])
        ],
        fetchReply: true
    })) as Message;
    let i;
    try {
        i = await m.awaitMessageComponent({
            time: 300000,
            filter: (i) => {
                return (
                    i.user.id === interaction.user.id &&
                    i.channel!.id === interaction.channel!.id &&
                    i.message.id === m.id
                );
            }
        });
        await i.deferUpdate();
    } catch {
        return;
    }
    const data = {
        meta: {
            type: "ticketDeleted",
            displayName: "Ticket Deleted",
            calculateType: "ticketUpdate",
            color: NucleusColors.red,
            emoji: "GUILD.TICKET.CLOSE",
            timestamp: Date.now()
        },
        list: {
            ticketFor: entry(member.id, renderUser(member.user)),
            deletedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as User)),
            deleted: entry(Date.now().toString(), renderDelta(Date.now())),
            transcript: entry(code, `https://clicks.codes/nucleus/transcript/${code}`)
        },
        hidden: {
            guild: interaction.guild!.id
        }
    };
    log(data);
    await interaction.channel.delete();
    return;
}
