import {
    ActionRowBuilder,
    CommandInteraction,
    StringSelectMenuBuilder,
    ApplicationCommandOptionType,
    ApplicationCommandType,
    StringSelectMenuOptionBuilder,
    SlashCommandBuilder,
    StringSelectMenuInteraction,
    ComponentType,
    APIMessageComponentEmoji,
    ApplicationCommandSubGroup,
    PermissionsBitField,
    Interaction,
    ApplicationCommandOption,
    ApplicationCommandSubCommand
} from "discord.js";
import client from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import { LoadingEmbed } from "../utils/defaults.js";
import { capitalize } from "../utils/generateKeyValueList.js";
import { getCommandByName, getCommandMentionByName } from "../utils/getCommandDataByName.js";
import getEmojiByName from "../utils/getEmojiByName.js";

const command = new SlashCommandBuilder().setName("help").setDescription("Shows help for commands").setDMPermission(true);

const styles: Record<string, { emoji: string }> = {
    help: { emoji: "NUCLEUS.LOGO" },
    mod: { emoji: "PUNISH.BAN.RED" },
    nucleus: { emoji: "NUCLEUS.LOGO" },
    privacy: { emoji: "NUCLEUS.LOGO" },
    role: { emoji: "GUILD.ROLES.DELETE" },
    rolemenu: { emoji: "GUILD.ROLES.DELETE" },
    server: { emoji: "GUILD.RED" },
    settings: { emoji: "GUILD.SETTINGS.RED" },
    tag: { emoji: "PUNISH.NICKNAME.RED" },
    tags: { emoji: "PUNISH.NICKNAME.RED" },
    ticket: { emoji: "GUILD.TICKET.CLOSE" },
    user: { emoji: "MEMBER.LEAVE" },
    verify: { emoji: "CONTROL.REDTICK" }
};

const callback = async (interaction: CommandInteraction): Promise<void> => {
    const m = await interaction.reply({ embeds: LoadingEmbed, ephemeral: true, fetchReply: true });
    const commands = client.fetchedCommands;

    let closed = false;
    let currentPath: [string, string, string] = ["", "", ""];
    do {
        const commandRow = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("commandRow")
                .setPlaceholder("Select a command")
                .addOptions(
                    ...commands
                        .filter((command) => command.type === ApplicationCommandType.ChatInput)
                        .map((command) => {
                            const builder = new StringSelectMenuOptionBuilder()
                                .setLabel(capitalize(command.name))
                                .setValue(command.name)
                                .setDescription(command.description)
                                .setDefault(currentPath[0] === command.name);
                            if (styles[command.name])
                                builder.setEmoji(
                                    getEmojiByName(styles[command.name]!.emoji, "id") as APIMessageComponentEmoji
                                );
                            return builder;
                        })
                )
        );
        const subcommandGroupRow = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder().setCustomId("subcommandGroupRow")
        );
        const subcommandRow = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder().setCustomId("subcommandRow")
        );
        const embed = new EmojiEmbed().setTitle("Help").setStatus("Danger").setEmoji("NUCLEUS.LOGO");

        if (currentPath[0] === "" || currentPath[0] === "help") {
            embed.setDescription(
                `Welcome to Nucleus\n\n` +
                    `Select a command to get started${
                        (interaction.member?.permissions as PermissionsBitField).has("ManageGuild")
                            ? `, or run ${getCommandMentionByName("nucleus/guide")} for commands to set up your server`
                            : ``
                    }\n\n\n` +
                    `Nucleus is fully [open source](https://github.com/clicksminuteper/Nucleus), and all currently free features will remain free forever.\n\n` +
                    `You can invite Nucleus to your server using ${getCommandMentionByName("nucleus/invite")}\n` +
                    `Our support server can be found [here](https://discord.gg/bPaNnxe), and we can be emailed at support@clicks.codes`
            );
        } else {
            const currentData = getCommandByName(
                currentPath.filter((value) => value !== "" && value !== "none").join("/")
            );
            const current = commands.find((command) => command.name === currentPath[0])!;

            let optionString = ``;
            let options: (ApplicationCommandOption & {
                nameLocalized?: string;
                descriptionLocalized?: string;
            })[] = [];
            //options
            if (
                currentPath[1] !== "" &&
                currentPath[1] !== "none" &&
                currentPath[2] !== "" &&
                currentPath[2] !== "none"
            ) {
                const Op = current.options.find(
                    (option) => option.name === currentPath[1]
                )! as ApplicationCommandSubGroup;
                const Op2 = Op.options!.find((option) => option.name === currentPath[2])!;
                options = Op2.options ?? [];
            } else if (currentPath[1] !== "" && currentPath[1] !== "none") {
                let Op = current.options.find((option) => option.name === currentPath[1])!;
                if (Op.type === ApplicationCommandOptionType.SubcommandGroup) {
                    options = [];
                } else {
                    Op = Op as ApplicationCommandSubCommand;
                    options = Op.options ?? [];
                }
            } else {
                options = current.options.filter(
                    (option) =>
                        option.type !== ApplicationCommandOptionType.SubcommandGroup &&
                        option.type !== ApplicationCommandOptionType.Subcommand
                );
            }
            for (const option of options) {
                optionString += ` - \`${option.name}\` (${ApplicationCommandOptionType[option.type].replace("Integer", "Number").replace("String", "Text")}) - ${
                    option.description
                }\n`;
            }
            const APICommand =
                client.commands[
                    "commands/" + currentPath.filter((value) => value !== "" && value !== "none").join("/")
                ]![0];
            let allowedToRun = true;
            if (interaction.guild && APICommand?.check) {
                allowedToRun = await APICommand.check(interaction as Interaction, true);
            }
            embed.setDescription(
                `${getEmojiByName(styles[currentPath[0]]!.emoji)} **${capitalize(currentData.name)}** | ${currentData.mention}\n\n` +
                    `${currentData.description}\n\n` +
                    (APICommand
                        ? `${getEmojiByName(allowedToRun ? "CONTROL.TICK" : "CONTROL.CROSS")} You ${
                              allowedToRun ? "" : "don't "
                          }` + `have permission to use this command\n\n`
                        : "") +
                    (optionString.length > 0 ? "**Options:**\n" + optionString : "")
            );
            const subcommands = current.options.filter(
                (option) => option.type === ApplicationCommandOptionType.Subcommand
            );
            const subcommandGroups = current.options.filter(
                (option) => option.type === ApplicationCommandOptionType.SubcommandGroup
            );

            if (subcommandGroups.length > 0) {
                subcommandGroupRow.components[0]!.addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Select a subcommand")
                        .setValue("none")
                        .setDefault(currentPath[1] === "none"),
                    ...subcommandGroups.map((option) =>
                        new StringSelectMenuOptionBuilder()
                            .setLabel(capitalize(option.name))
                            .setValue(option.name)
                            .setDefault(currentPath[1] === option.name)
                    )
                );
                if (
                    subcommandGroupRow.components[0]!.options.find(
                        (option) => option.data.default && option.data.value !== "none"
                    )
                ) {
                    const subsubcommands =
                        (
                            subcommandGroups.find(
                                (option) => option.name === currentPath[1]
                            )! as ApplicationCommandSubGroup
                        ).options ?? [];
                    subcommandRow.components[0]!.addOptions(
                        new StringSelectMenuOptionBuilder()
                            .setLabel("Select a subcommand")
                            .setValue("none")
                            .setDefault(currentPath[2] === "none"),
                        ...subsubcommands.map((option) =>
                            new StringSelectMenuOptionBuilder()
                                .setLabel(capitalize(option.name))
                                .setValue(option.name)
                                .setDefault(currentPath[2] === option.name)
                        )
                    );
                }
            }
            if (subcommands.length > 0) {
                subcommandGroupRow.components[0]!.addOptions(
                    ...subcommands.map((option) =>
                        new StringSelectMenuOptionBuilder()
                            .setLabel(capitalize(option.name))
                            .setValue(option.name)
                            .setDefault(currentPath[1] === option.name)
                    )
                );
            }
        }

        const cmps = [commandRow];
        if (subcommandGroupRow.components[0]!.options.length > 0) cmps.push(subcommandGroupRow);
        if (subcommandRow.components[0]!.options.length > 0) cmps.push(subcommandRow);

        await interaction.editReply({ embeds: [embed], components: cmps });

        let i: StringSelectMenuInteraction;
        try {
            i = await m.awaitMessageComponent<ComponentType.StringSelect>({
                filter: (newInteraction) => interaction.user.id === newInteraction.user.id,
                time: 300000
            });
        } catch (e) {
            closed = true;
            continue;
        }
        await i.deferUpdate();
        const value = i.values[0]!;
        switch (i.customId) {
            case "commandRow": {
                currentPath = [value, "", ""];
                break;
            }
            case "subcommandGroupRow": {
                currentPath = [currentPath[0], value, ""];
                break;
            }
            case "subcommandRow": {
                currentPath[2] = value;
                break;
            }
        }
    } while (!closed);
};

export { command as command };
export { callback };
