import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, Message, ActionRowBuilder, StringSelectMenuBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuOptionBuilder, APIMessageComponentEmoji, TextInputBuilder, StringSelectMenuInteraction, ButtonInteraction } from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import client from "../../utils/client.js";
import convertCurlyBracketString from "../../utils/convertCurlyBracketString.js";
import singleNotify from "../../utils/singleNotify.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import createPageIndicator from "../../utils/createPageIndicator.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";


const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("stats")
        .setDescription("Controls channels which update when someone joins or leaves the server")


const showModal = async (interaction: StringSelectMenuInteraction, current: { enabled: boolean; name: string; }) => {
    await interaction.showModal(
        new Discord.ModalBuilder()
            .setCustomId("modal")
            .setTitle(`Stats channel name`)
            .addComponents(
                new ActionRowBuilder<TextInputBuilder>().addComponents(
                    new TextInputBuilder()
                        .setCustomId("ex1")
                        .setLabel("Server Info (1/3)")
                        .setPlaceholder(
                            `{serverName} - This server's name\n\n` +
                            `These placeholders will be replaced with the server's name, etc..`
                        )
                        .setMaxLength(1)
                        .setRequired(false)
                        .setStyle(Discord.TextInputStyle.Paragraph)
                ),
                new ActionRowBuilder<TextInputBuilder>().addComponents(
                    new TextInputBuilder()
                        .setCustomId("ex2")
                        .setLabel("Member Counts (2/3) - {MemberCount:...}")
                        .setPlaceholder(
                            `{:all} - Total member count\n` +
                            `{:humans} - Total non-bot users\n` +
                            `{:bots} - Number of bots\n`
                        )
                        .setMaxLength(1)
                        .setRequired(false)
                        .setStyle(Discord.TextInputStyle.Paragraph)
                ),
                new ActionRowBuilder<TextInputBuilder>().addComponents(
                    new TextInputBuilder()
                        .setCustomId("ex3")
                        .setLabel("Latest Member (3/3) - {member:...}")
                        .setPlaceholder(
                                `{:name} - The members name\n`
                        )
                        .setMaxLength(1)
                        .setRequired(false)
                        .setStyle(Discord.TextInputStyle.Paragraph)
                ),
                new ActionRowBuilder<TextInputBuilder>().addComponents(
                    new TextInputBuilder()
                        .setCustomId("text")
                        .setLabel("Channel name input")
                        .setMaxLength(1000)
                        .setRequired(true)
                        .setStyle(Discord.TextInputStyle.Short)
                        .setValue(current.name)
                )
            )
    );
}

const callback = async (interaction: CommandInteraction) => {
    if (!interaction.guild) return;
    const { renderChannel } = client.logger;
    const m: Message = await interaction.reply({ embeds: LoadingEmbed, ephemeral: true, fetchReply: true });
    let page = 0;
    let closed = false;
    const config = await client.database.guilds.read(interaction.guild.id);
    const currentObject = config.stats;
    let modified = false;
    do {
        let embed = new EmojiEmbed()
            .setTitle("Stats Settings")
            .setEmoji("SETTINGS.STATS.GREEN")
            .setStatus("Success");
        const noStatsChannels = Object.keys(currentObject).length === 0;
        let current: { enabled: boolean; name: string; };

        const pageSelect = new StringSelectMenuBuilder()
            .setCustomId("page")
            .setPlaceholder("Select a stats channel to manage");
        const actionSelect = new StringSelectMenuBuilder()
            .setCustomId("action")
            .setPlaceholder("Perform an action")
            .addOptions(
                new StringSelectMenuOptionBuilder()
                    .setLabel("Edit")
                    .setDescription("Edit the stats channel")
                    .setValue("edit")
                    .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
                new StringSelectMenuOptionBuilder()
                    .setLabel("Delete")
                    .setDescription("Delete the stats channel")
                    .setValue("delete")
                    .setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji)
        );
        const buttonRow = new ActionRowBuilder<ButtonBuilder>()
                .addComponents(
                    new ButtonBuilder()
                        .setCustomId("back")
                        .setStyle(ButtonStyle.Primary)
                        .setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji)
                        .setDisabled(page === 0),
                    new ButtonBuilder()
                        .setCustomId("next")
                        .setEmoji(getEmojiByName("CONTROL.RIGHT", "id") as APIMessageComponentEmoji)
                        .setStyle(ButtonStyle.Primary)
                        .setDisabled(page === Object.keys(currentObject).length - 1),
                    new ButtonBuilder()
                        .setCustomId("add")
                        .setLabel("Create new")
                        .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id") as APIMessageComponentEmoji)
                        .setStyle(ButtonStyle.Secondary)
                        .setDisabled(Object.keys(currentObject).length >= 24),
                    new ButtonBuilder()
                        .setCustomId("save")
                        .setLabel("Save")
                        .setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji)
                        .setStyle(ButtonStyle.Success)
                        .setDisabled(modified),
            );
        if (noStatsChannels) {
            embed.setDescription("No stats channels have been set up yet. Use the button below to add one.\n\n" +
                createPageIndicator(1, 1, undefined, true)
            );
            pageSelect.setDisabled(true);
            actionSelect.setDisabled(true);
            pageSelect.addOptions(new StringSelectMenuOptionBuilder()
                .setLabel("No stats channels")
                .setValue("none")
            );
        } else {
            page = Math.min(page, Object.keys(currentObject).length - 1);
            current = currentObject[Object.keys(config.stats)[page]!]!
            actionSelect.addOptions(new StringSelectMenuOptionBuilder()
                .setLabel(current.enabled ? "Disable" : "Enable")
                .setValue("toggleEnabled")
                .setDescription(`Currently ${current.enabled ? "Enabled" : "Disabled"}, click to ${current.enabled ? "disable" : "enable"} this channel`)
                .setEmoji(getEmojiByName(current.enabled ? "CONTROL.TICK" : "CONTROL.CROSS", "id") as APIMessageComponentEmoji)
            );

            embed.setDescription(`**Currently Editing:** ${renderChannel(Object.keys(currentObject)[page]!)}\n\n` +
                `${getEmojiByName(current.enabled ? "CONTROL.TICK" : "CONTROL.CROSS")} Currently ${current.enabled ? "Enabled" : "Disabled"}\n` +
                `**Name:** \`${current.name}\`\n` +
                `**Preview:** ${await convertCurlyBracketString(current.name, interaction.user.id, interaction.user.username, interaction.guild.name, interaction.guild.members)}` + '\n\n' +
                createPageIndicator(Object.keys(config.stats).length, page)
            );
            for (const [id, { name, enabled }] of Object.entries(currentObject)) {
                pageSelect.addOptions(new StringSelectMenuOptionBuilder()
                    .setLabel(`${name} (${renderChannel(id)})`)
                    .setEmoji(getEmojiByName(enabled ? "CONTROL.TICK" : "CONTROL.CROSS", "id") as APIMessageComponentEmoji)
                    .setDescription(`${enabled ? "Enabled" : "Disabled"}`)
                    .setValue(id)
                );
            }
        }

        interaction.editReply({embeds: [embed], components: [
            new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(pageSelect),
            new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(actionSelect),
            buttonRow
        ]});

        let i: StringSelectMenuInteraction | ButtonInteraction;
        try {
            i = await m.awaitMessageComponent({ filter: (interaction) => interaction.user.id === interaction.user.id, time: 60000 }) as StringSelectMenuInteraction | ButtonInteraction;
        } catch (e) {
            closed = true;
            continue;
        }

        if(i.isStringSelectMenu()) {
            switch(i.customId) {
                case "page":
                    page = Object.keys(currentObject).indexOf(i.values[0]!);
                    break;
                case "action":
                    modified = true;
                    switch(i.values[0]!) {
                        case "edit": {
                            showModal(i, current!)
                            await interaction.editReply({
                                embeds: [
                                    new EmojiEmbed()
                                        .setTitle("Stats Channel")
                                        .setDescription("Modal opened. If you can't see it, click back and try again.")
                                        .setStatus("Success")
                                        .setEmoji("SETTINGS.STATS.GREEN")
                                ],
                                components: [
                                    new ActionRowBuilder<ButtonBuilder>().addComponents(
                                        new ButtonBuilder()
                                            .setLabel("Back")
                                            .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                                            .setStyle(ButtonStyle.Primary)
                                            .setCustomId("back")
                                    )
                                ]
                            });
                            break;
                        }
                        case "toggleEnabled": {
                            i.deferUpdate();
                            currentObject[Object.keys(currentObject)[page]!]!.enabled = !currentObject[Object.keys(currentObject)[page]!]!.enabled;
                            modified = true;
                            break;
                        }
                        case "delete": {
                            i.deferUpdate();
                            delete currentObject[Object.keys(currentObject)[page]!];
                            modified = true;
                            break;
                        }
                    }
                    break;
            }
        } else {
            i.deferUpdate();
            switch(i.customId) {
                case "back":
                    page--;
                    break;
                case "next":
                    page++;
                    break;
                case "add":
                    break;
                case "save":
                    client.database.guilds.write(interaction.guild.id, {stats: currentObject});
                    singleNotify("statsChannelDeleted", interaction.guild.id, true);
                    modified = false;
                    break;
            }
        }

    } while (!closed);
};

const check = (interaction: CommandInteraction) => {
    const member = interaction.member as Discord.GuildMember;
    if (!member.permissions.has("ManageChannels"))
        return "You must have the *Manage Channels* permission to use this command";
    return true;
};


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