import { LoadingEmbed } from "../utils/defaultEmbeds.js";
import { CommandInteraction, GuildChannel, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
import { SlashCommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import client from "../utils/client.js";
import addPlural from "../utils/plurals.js";
import getEmojiByName from "../utils/getEmojiByName.js";

const command = new SlashCommandBuilder()
    .setName("categorise")
    .setDescription("Categorises your servers channels");

const callback = async (interaction: CommandInteraction): Promise<any> => {
    const channels = interaction.guild.channels.cache.filter(c => c.type !== "GUILD_CATEGORY");
    const categorised = {};
    await interaction.reply({embeds: LoadingEmbed, ephemeral: true});
    const predicted = {};
    const types = {
        general: ["general", "muted", "main", "topic", "discuss"],
        commands: ["bot", "command", "music"],
        images: ["pic", "selfies", "image"],
        nsfw: ["porn", "nsfw", "sex"],
        links: ["links"],
        advertising: ["ads", "advert", "server", "partner"],
        staff: ["staff", "mod", "admin"],
        spam: ["spam"],
        other: ["random"]
    };
    for (const c of channels.values()) {
        for (const type in types) {
            for (const word of types[type]) {
                if (c.name.toLowerCase().includes(word)) {
                    predicted[c.id] = predicted[c.id] ?? [];
                    predicted[c.id].push(type);
                }
            }
        }
    }
    let m;
    for (const c of channels) {
        // convert channel to a channel if its a string
        let channel: any;
        if (typeof c === "string") channel = interaction.guild.channels.cache.get(channel).id;
        else channel = (c[0] as unknown as GuildChannel).id;
        console.log(channel);
        if (!predicted[channel]) predicted[channel] = [];
        m = await interaction.editReply({embeds: [new EmojiEmbed()
            .setTitle("Categorise")
            .setDescription(`Select all types that apply to <#${channel}>.\n\n` +
            `${addPlural(predicted[channel].length, "Suggestion")}: ${predicted[channel].join(", ")}`)
            .setEmoji("CHANNEL.CATEGORY.CREATE")
            .setStatus("Success")
        ], components: [
            new MessageActionRow().addComponents([new MessageSelectMenu()
                .setCustomId("selected")
                .setMaxValues(Object.keys(types).length)
                .setMinValues(1)
                .setPlaceholder("Select all types that apply to this channel")
                .setOptions(Object.keys(types).map(type => ({label: type, value: type})))
            ]),
            new MessageActionRow().addComponents([
                new MessageButton().setLabel("Accept Suggestion").setCustomId("accept").setStyle("SUCCESS").setDisabled(predicted[channel].length === 0)
                    .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.TICK", "id"))),
                new MessageButton().setLabel("Use \"Other\"").setCustomId("reject").setStyle("SECONDARY")
                    .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.CROSS", "id")))
            ])
        ]});
        let i;
        try {
            i = await m.awaitMessageComponent({ time: 300000 });
        } catch (e) {
            return await interaction.editReply({embeds: [new EmojiEmbed()
                .setTitle("Categorise")
                .setEmoji("CHANNEL.CATEGORY.DELETE")
                .setStatus("Danger")
                .setDescription(`Select all types that apply to <#${channel}>.\n\n` +
                `${addPlural(predicted[channel].length, "Suggestion")}: ${predicted[channel].join(", ")}`)
                .setFooter({text: "Message timed out"})
            ]});
        }
        i.deferUpdate();
        let selected;
        if (i.customId === "select") { selected = i.values; }
        if (i.customId === "accept") { selected = predicted[channel]; }
        if (i.customId === "reject") { selected = ["other"]; }
        categorised[channel] = selected;
    }
    console.log(categorised);
};

const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
    return true;
};

export { command };
export { callback };
export { check };