import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, Message, ActionRowBuilder, StringSelectMenuBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuOptionBuilder, APIMessageComponentEmoji, MessageComponentInteraction, TextInputBuilder } 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 { callback as statsChannelAddCallback } from "../../reflex/statsChannelUpdate.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";
import type { GuildConfig } from "../../utils/database.js";

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

type ChangesType = Record<string, { name?: string; enabled?: boolean; }>

const applyChanges = (baseObject: GuildConfig['stats'], changes: ChangesType): GuildConfig['stats'] => {
    for (const [id, { name, enabled }] of Object.entries(changes)) {
        if (!baseObject[id]) baseObject[id] = { name: "", enabled: false};
        if (name) baseObject[id]!.name = name;
        if (enabled) baseObject[id]!.enabled = enabled;
    }
    return baseObject;
}


const callback = async (interaction: CommandInteraction) => {
    try{
    if (!interaction.guild) return;
    const { renderChannel } = client.logger;
    let closed = false;
    let page = 0;
    const m: Message = await interaction.reply({ embeds: LoadingEmbed, ephemeral: true, fetchReply: true });
    let changes: ChangesType = {};
    do {
        const config = await client.database.guilds.read(interaction.guild.id);
        const stats = config.stats;
        let currentID = "";
        let current: {
            name: string;
            enabled: boolean;
        } = {
            name: "",
            enabled: false
        };
        let description = "";
        let pageSelect = new StringSelectMenuBuilder()
            .setCustomId("page")
            .setPlaceholder("Select a stats channel to manage")
            .setDisabled(Object.keys(stats).length === 0)
            .setMinValues(1)
            .setMaxValues(1);
        let actionSelect = new StringSelectMenuBuilder()
            .setCustomId("action")
            .setPlaceholder("Perform an action")
            .setMinValues(1)
            .setMaxValues(1)
            .setDisabled(Object.keys(stats).length === 0)
            .addOptions(
                new StringSelectMenuOptionBuilder()
                    .setLabel("Edit")
                    .setValue("edit")
                    .setDescription("Edit the name of this stats channel")
                    .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
                new StringSelectMenuOptionBuilder()
                    .setLabel("Delete")
                    .setValue("delete")
                    .setDescription("Delete this stats channel")
                    .setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji)
            );
        if (Object.keys(stats).length === 0) {
            description = "You do not have any stats channels set up yet"
            pageSelect.addOptions(new StringSelectMenuOptionBuilder().setLabel("No stats channels").setValue("none"))
        } else {
            currentID = Object.keys(stats)[page]!
            current = stats[currentID]!;
            current = applyChanges({ [currentID]: current }, changes)[currentID]!;
            // Propogate pageSelect with list of stats channels
            for (const [id, { name, enabled }] of Object.entries(stats)) {
                pageSelect.addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel(name)
                        .setValue(id)
                        .setDescription(`Enabled: ${enabled}`)
                );
            }
            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)
            );
            description = `**Currently Editing:** ${renderChannel(currentID)}\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)}`
        }
        const row = 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(stats).length - 1),
                new ButtonBuilder()
                    .setCustomId("add")
                    .setLabel("Create new")
                    .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id") as APIMessageComponentEmoji)
                    .setStyle(ButtonStyle.Secondary)
                    .setDisabled(Object.keys(stats).length >= 24),
                new ButtonBuilder()
                    .setCustomId("save")
                    .setLabel("Save")
                    .setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji)
                    .setStyle(ButtonStyle.Success)
                    .setDisabled(Object.keys(changes).length === 0),
            );

        let embed = new EmojiEmbed()
            .setTitle("Stats Channels")
            .setDescription(description + "\n\n" + createPageIndicator(Object.keys(stats).length, page))
            .setEmoji("SETTINGS.STATS.GREEN")
            .setStatus("Success")

        interaction.editReply({
            embeds: [embed],
            components: [
                new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(pageSelect),
                new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(actionSelect),
                row
            ]
        });
        let i: MessageComponentInteraction;
        try {
            i = await m.awaitMessageComponent({ filter: (i) => i.user.id === interaction.user.id, time: 30000 });
        } catch (e) {
            closed = true;
            continue;
        }
        if (i.isStringSelectMenu()) {
            switch(i.customId) {
                case "page":
                    page = Object.keys(stats).indexOf(i.values[0]!);
                    i.deferUpdate();
                    break;
                case "action":
                    if(!changes[currentID]) changes[currentID] = {};
                    switch(i.values[0]!) {
                        case "edit":
                            await i.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)
                                        )
                                    )
                            );
                            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")
                                    )
                                ]
                            });
                            let out: Discord.ModalSubmitInteraction | null;
                            try {
                                out = await modalInteractionCollector(
                                    m,
                                    (m) => m.channel!.id === interaction.channel!.id,
                                    (_) => true
                                ) as Discord.ModalSubmitInteraction | null;
                            } catch (e) {
                                continue;
                            }
                            if (!out) continue
                            if (!out.fields) continue
                            if (out.isButton()) continue;
                            const newString = out.fields.getTextInputValue("text");
                            if (!newString) continue;
                            changes[currentID]!.name = newString;
                            break;
                        case "delete":
                            changes[currentID] = {};
                            i.deferUpdate();
                            break;
                        case "toggleEnabled":
                            changes[currentID]!.enabled = !stats[currentID]!.enabled;
                            i.deferUpdate();
                            break;
                    }
                    break;
            }
        } else if (i.isButton()) {
            i.deferUpdate();
            switch(i.customId) {
                case "back":
                    page--;
                    break;
                case "next":
                    page++;
                    break;
                case "add":
                    break;
                case "save":
                    let changed = applyChanges(config.stats, changes);
                    singleNotify("statsChannelDeleted", interaction.guild.id, true)
                    config.stats = changed;
                    changes = {}
                    await client.database.guilds.write(interaction.guildId!, config);
            }
        }
        console.log(changes, config.stats);
    } while (!closed);
    } catch(e) {
        console.log(e)
    }
};

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 };