import Discord, {
    CategoryChannel,
    CommandInteraction,
    GuildMember,
    MessageActionRow,
    MessageButton,
    MessageSelectMenu
} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import pageIndicator from "../../utils/createPageIndicator.js";

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("viewas")
        .setDescription("View the server as a specific member")
        .addUserOption((option) =>
            option
                .setName("member")
                .setDescription("The member to view as")
                .setRequired(true)
        );

const callback = async (interaction: CommandInteraction): Promise<void> => {
    let channels = [];
    let m;
    interaction.guild.channels.cache.forEach((channel) => {
        if (!channel.parent && channel.type !== "GUILD_CATEGORY")
            channels.push(channel);
    });
    channels = [channels];
    channels = channels.concat(
        interaction.guild.channels.cache
            .filter((c) => c.type === "GUILD_CATEGORY")
            .map((c) => (c as CategoryChannel).children.map((c) => c))
    );
    const autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"];
    channels = channels.map((c) =>
        c.sort((a, b) => {
            if (
                autoSortBelow.includes(a.type) &&
                autoSortBelow.includes(b.type)
            )
                return a.position - b.position;
            if (autoSortBelow.includes(a.type)) return 1;
            if (autoSortBelow.includes(b.type)) return -1;
            return a.position - b.position;
        })
    );
    // Sort all arrays by the position of the first channels parent position
    channels = channels.sort((a, b) => {
        if (!a[0].parent) return -1;
        if (!b[0].parent) return 1;
        return a[0].parent.position - b[0].parent.position;
    });
    const member = interaction.options.getMember(
        "member"
    ) as Discord.GuildMember;
    m = await interaction.reply({
        embeds: [
            new EmojiEmbed()
                .setEmoji("MEMBER.JOIN")
                .setTitle("Viewing as " + member.displayName)
                .setStatus("Success")
        ],
        ephemeral: true,
        fetchReply: true
    });
    let page = 0;
    while (true) {
        m = await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("MEMBER.JOIN")
                    .setTitle("Viewing as " + member.displayName)
                    .setStatus("Success")
                    .setDescription(
                        `**${
                            channels[page][0].parent
                                ? channels[page][0].parent.name
                                : "Uncategorised"
                        }**` +
                            "\n" +
                            channels[page]
                                .map((c) => {
                                    let channelType = c.type;
                                    if (
                                        interaction.guild.rulesChannelId ===
                                        c.id
                                    )
                                        channelType = "RULES";
                                    else if ("nsfw" in c && c.nsfw)
                                        channelType += "_NSFW";
                                    return c
                                        .permissionsFor(member)
                                        .has("VIEW_CHANNEL")
                                        ? `${getEmojiByName(
                                              "ICONS.CHANNEL." + channelType
                                          )} ${c.name}\n` +
                                              (() => {
                                                  if (
                                                      "threads" in c &&
                                                      c.threads.cache.size > 0
                                                  ) {
                                                      return (
                                                          c.threads.cache
                                                              .map(
                                                                  (t) =>
                                                                      ` ${
                                                                          getEmojiByName(
                                                                              "ICONS.CHANNEL.THREAD_PIPE"
                                                                          ) +
                                                                          " " +
                                                                          getEmojiByName(
                                                                              "ICONS.CHANNEL.THREAD_CHANNEL"
                                                                          )
                                                                      } ${
                                                                          t.name
                                                                      }`
                                                              )
                                                              .join("\n") + "\n"
                                                      );
                                                  }
                                                  return "";
                                              })()
                                        : "";
                                })
                                .join("") +
                            "\n" +
                            pageIndicator(channels.length, page)
                    )
            ],
            components: [
                new MessageActionRow().addComponents([
                    new MessageSelectMenu()
                        .setOptions(
                            channels.map((c, index) => ({
                                label: c[0].parent
                                    ? c[0].parent.name
                                    : "Uncategorised",
                                value: index.toString(),
                                default: page === index
                            }))
                        )
                        .setCustomId("select")
                        .setMaxValues(1)
                        .setMinValues(1)
                        .setPlaceholder("Select a category")
                ]),
                new MessageActionRow().addComponents([
                    new MessageButton()
                        .setLabel(
                            page === 0
                                ? ""
                                : channels[page - 1][0].parent
                                ? channels[page - 1][0].parent.name
                                : "Uncategorised"
                        )
                        .setDisabled(page === 0)
                        .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                        .setStyle("PRIMARY")
                        .setCustomId("previous"),
                    new MessageButton()
                        .setLabel(
                            page === channels.length - 1
                                ? ""
                                : channels[page + 1][0].parent
                                ? channels[page + 1][0].parent.name
                                : "Uncategorised"
                        )
                        .setDisabled(page === channels.length - 1)
                        .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
                        .setStyle("PRIMARY")
                        .setCustomId("next")
                ])
            ]
        });
        let i;
        try {
            i = await m.awaitMessageComponent({ time: 300000 });
        } catch (e) {
            return;
        }
        i.deferUpdate();
        if (i.customId === "next") {
            page++;
        } else if (i.customId === "previous") {
            page--;
        } else if (i.customId === "select") {
            page = parseInt(i.values[0]);
        }
    }
};

const check = (interaction: CommandInteraction) => {
    const member = interaction.member as GuildMember;
    if (!member.permissions.has("MANAGE_ROLES"))
        throw "You do not have the *Manage Roles* permission";
    return true;
};

export { command, callback, check };
