import Discord, { CategoryChannel, CommandInteraction, GuildMember, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import { WrappedCheck } from "jshaiku";
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<any> => {
    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, defaultCheck: WrappedCheck) => {
    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 };