import Discord, { CommandInteraction, MessageActionRow, Message, MessageButton, TextInputComponent } from "discord.js";
import { modalInteractionCollector } from "./dualCollector.js";
import EmojiEmbed from "./generateEmojiEmbed.js";
import getEmojiByName from "./getEmojiByName.js";


interface CustomBoolean<T> {
    title: string;
    disabled: boolean;
    value: string | null;
    emoji: string | undefined;
    active: boolean;
    onClick: () => Promise<T>;
    response: T | null;
}

class confirmationMessage {
    interaction: CommandInteraction;
    title = "";
    emoji = "";
    description = "";
    color = "";
    customButtons: {[index:string]: CustomBoolean<unknown>} = {};
    inverted = false;
    reason: string | null = null;

    constructor(interaction: CommandInteraction) {
        this.interaction = interaction;
    }

    setTitle(title: string) { this.title = title; return this; }
    setEmoji(emoji: string) { this.emoji = emoji; return this; }
    setDescription(description: string) { this.description = description; return this; }
    setColor(color: string) { this.color = color; return this; }
    setInverted(inverted: boolean) { this.inverted = inverted; return this; }
    addCustomBoolean(customId: string, title: string, disabled: boolean, callback: () => Promise<unknown> | null, callbackClicked: string | null, emoji?: string, initial?: boolean) {        this.customButtons[customId] = {
        title: title,
        disabled: disabled,
        value: callbackClicked,
        emoji: emoji,
        active: initial ?? false,
        onClick: callback ?? (() => null),
        response: null
    };
    return this;
    }
    addReasonButton(reason: string) {
        this.reason = reason;
        return this;
    }
    async send(editOnly?: boolean) {
        while (true) {
            const fullComponents = [
                new Discord.MessageButton()
                    .setCustomId("yes")
                    .setLabel("Confirm")
                    .setStyle(this.inverted ? "SUCCESS" : "DANGER")
                    .setEmoji(getEmojiByName("CONTROL.TICK", "id")),
                new Discord.MessageButton()
                    .setCustomId("no")
                    .setLabel("Cancel")
                    .setStyle("SECONDARY")
                    .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
            ];
            Object.entries(this.customButtons).forEach(([k, v]) => {
                fullComponents.push(new Discord.MessageButton()
                    .setCustomId(k)
                    .setLabel(v.title)
                    .setStyle(v.active ? "SUCCESS" : "PRIMARY")
                    .setEmoji(getEmojiByName(v.emoji, "id"))
                    .setDisabled(v.disabled));
            });
            if (this.reason !== null) fullComponents.push(new Discord.MessageButton()
                .setCustomId("reason")
                .setLabel("Edit Reason")
                .setStyle("PRIMARY")
                .setEmoji(getEmojiByName("ICONS.EDIT", "id"))
                .setDisabled(false)
            );
            const components = [];
            for (let i = 0; i < fullComponents.length; i += 5) {
                components.push(new MessageActionRow().addComponents(fullComponents.slice(i, i + 5)));
            }
            const object = {
                embeds: [
                    new EmojiEmbed()
                        .setEmoji(this.emoji)
                        .setTitle(this.title)
                        .setDescription(this.description + "\n\n" + Object.values(this.customButtons).map(v => {
                            if (v.value === null) return "";
                            return v.active ? `*${v.value}*\n` : "";
                        }).join(""))
                        .setStatus(this.color)
                ],
                components: components,
                ephemeral: true,
                fetchReply: true
            };
            let m;
            try {
                if ( editOnly ) {
                    m = await this.interaction.editReply(object);
                } else {
                    m = await this.interaction.reply(object);
                }
            } catch { return { cancelled: true }; }
            let component;
            try {
                component = await (m as Message).awaitMessageComponent({filter: (m) => m.user.id === this.interaction.user.id, time: 300000});
            } catch (e) {
                return { success: false, components: this.customButtons };
            }
            if (component.customId === "yes") {
                component.deferUpdate();
                for (const v of Object.values(this.customButtons)) {
                    if (!v.active) continue;
                    try { v.response = await v.onClick(); }
                    catch (e) { console.log(e); }
                }
                return { success: true, components: this.customButtons };
            } else if (component.customId === "no") {
                component.deferUpdate();
                return { success: false, components: this.customButtons };
            } else if (component.customId === "reason") {
                await component.showModal(new Discord.Modal().setCustomId("modal").setTitle("Editing reason").addComponents(
                    new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
                        .setCustomId("reason")
                        .setLabel("Reason")
                        .setMaxLength(2000)
                        .setRequired(false)
                        .setStyle("PARAGRAPH")
                        .setPlaceholder("Spammed in #general")
                        .setValue(this.reason ? this.reason : "")
                    )
                ));
                await this.interaction.editReply({
                    embeds: [new EmojiEmbed()
                        .setTitle(this.title)
                        .setDescription("Modal opened. If you can't see it, click back and try again.")
                        .setStatus(this.color)
                        .setEmoji(this.emoji)
                    ], components: [new MessageActionRow().addComponents([new MessageButton()
                        .setLabel("Back")
                        .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                        .setStyle("PRIMARY")
                        .setCustomId("back")
                    ])]
                });
                let out;
                try {
                    out = await modalInteractionCollector(m, (m) => m.channel.id === this.interaction.channel.id, (m) => m.customId === "reason");
                } catch (e) { return {}; }
                if (out.fields) { return { newReason: out.fields.getTextInputValue("reason") ?? "" }; }
                else { return { newReason: this.reason }; }
            } else {
                component.deferUpdate();
                this.customButtons[component.customId].active = !this.customButtons[component.customId].active;
                return { components: this.customButtons };
            }
        }
    }
}

export default confirmationMessage;
