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");

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")}`
            );
        } 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]})- ${
                    option.description
                }\n`;
            }
            const APICommand =
                client.commands[
                    "commands/" + currentPath.filter((value) => value !== "" && value !== "none").join("/")
                ]![0];
            let allowedToRun = true;
            if (APICommand?.check) {
                allowedToRun = await APICommand.check(interaction as Interaction, true);
            }
            embed.setDescription(
                `${getEmojiByName(styles[currentPath[0]]!.emoji)} **${capitalize(currentData.name)}**\n> ${
                    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 };
