import {
    ActionRowBuilder,
    APIMessageComponentEmoji,
    ButtonBuilder,
    ButtonStyle,
    ChannelSelectMenuBuilder,
    ChannelType,
    CommandInteraction,
    MessageCreateOptions,
    ModalBuilder,
    SlashCommandSubcommandBuilder,
    StringSelectMenuBuilder,
    StringSelectMenuOptionBuilder,
    TextInputBuilder,
    TextInputStyle
} from "discord.js";
import type Discord from "discord.js";
import { LoadingEmbed } from "../../utils/defaults.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import lodash from "lodash";
import getEmojiByName from "../../utils/getEmojiByName.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
import _ from "lodash";

export const command = new SlashCommandSubcommandBuilder()
    .setName("buttons")
    .setDescription("Create clickable buttons for verifying, role menus etc.");

interface Data {
    buttons: string[];
    title: string | null;
    description: string | null;
    color: number;
    channel: string | null;
}

const colors: Record<string, number> = {
    RED: 0xf27878,
    ORANGE: 0xe5ab71,
    YELLOW: 0xf2d478,
    GREEN: 0x65cc76,
    BLUE: 0x72aef5,
    PURPLE: 0xa358b2,
    PINK: 0xd46899,
    GRAY: 0x999999
};

const buttonNames: Record<string, string> = {
    verifybutton: "Verify",
    rolemenu: "Role Menu",
    createticket: "Create Ticket"
};

const presetButtons = [
    {
        title: "Verify",
        description: "Click the button below to get verified in the server.",
        buttons: ["verifybutton"],
        color: "GREEN"
    },
    {
        title: "Get Roles",
        description: "Click the button to choose which roles you would like in the server",
        buttons: ["rolemenu"],
        color: "BLUE"
    },
    {
        title: "Create Ticket",
        description: "Click the button below to create a ticket",
        buttons: ["createticket"],
        color: "RED"
    }
];

export const callback = async (interaction: CommandInteraction): Promise<void> => {
    const m = await interaction.reply({
        embeds: LoadingEmbed,
        fetchReply: true,
        ephemeral: true
    });

    let closed = false;
    let data: Data = {
        buttons: [],
        title: null,
        description: null,
        color: colors["RED"]!,
        channel: interaction.channelId
    };
    do {
        const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
            new ButtonBuilder()
                .setCustomId("edit")
                .setLabel("Edit Embed")
                .setStyle(ButtonStyle.Secondary)
                .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
            new ButtonBuilder()
                .setCustomId("send")
                .setLabel("Send")
                .setStyle(ButtonStyle.Primary)
                .setDisabled(!data.channel)
        );

        const colorSelect = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("color")
                .setPlaceholder("Select a color")
                .setMinValues(1)
                .addOptions(
                    Object.keys(colors).map((color: string) => {
                        return new StringSelectMenuOptionBuilder()
                            .setLabel(lodash.capitalize(color))
                            .setValue(color)
                            .setEmoji(getEmojiByName("COLORS." + color, "id") as APIMessageComponentEmoji)
                            .setDefault(data.color === colors[color]);
                    })
                )
        );

        const presetSelect = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("preset")
                .setPlaceholder("Select a preset")
                .setMaxValues(1)
                .addOptions(
                    presetButtons.map((preset, i) => {
                        return new StringSelectMenuOptionBuilder()
                            .setLabel(preset.title)
                            .setValue(i.toString())
                            .setDescription(preset.description)
                            .setEmoji(getEmojiByName("COLORS." + preset.color, "id") as APIMessageComponentEmoji);
                    })
                )
        );

        const buttonSelect = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
            new StringSelectMenuBuilder()
                .setCustomId("button")
                .setPlaceholder("Select buttons to add")
                .setMinValues(1)
                .setMaxValues(3)
                .addOptions(
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Verify")
                        .setValue("verifybutton")
                        .setDescription("Click to get verified in the server")
                        .setDefault(data.buttons.includes("verifybutton")),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Role Menu")
                        .setValue("rolemenu")
                        .setDescription("Click to customize your roles")
                        .setDefault(data.buttons.includes("rolemenu")),
                    new StringSelectMenuOptionBuilder()
                        .setLabel("Ticket")
                        .setValue("createticket")
                        .setDescription("Click to create a support ticket")
                        .setDefault(data.buttons.includes("createticket"))
                )
        );

        const channelMenu = new ActionRowBuilder<ChannelSelectMenuBuilder>().addComponents(
            new ChannelSelectMenuBuilder()
                .setCustomId("channel")
                .setPlaceholder("Select a channel")
                .setChannelTypes(
                    ChannelType.GuildText,
                    ChannelType.GuildAnnouncement,
                    ChannelType.PublicThread,
                    ChannelType.AnnouncementThread
                )
        );
        let channelName = interaction.guild!.channels.cache.get(data.channel!)?.name;
        if (data.channel === interaction.channelId) channelName = "this channel";
        const embed = new EmojiEmbed()
            .setTitle(data.title ?? "No title set")
            .setDescription(data.description ?? "*No description set*")
            .setColor(data.color)
            .setFooter({ text: `Click the button below to edit the embed | The embed will be sent in ${channelName}` });

        await interaction.editReply({
            embeds: [embed],
            components: [presetSelect, colorSelect, buttonSelect, channelMenu, buttons]
        });

        let i: Discord.ButtonInteraction | Discord.ChannelSelectMenuInteraction | Discord.StringSelectMenuInteraction;
        try {
            i = (await interaction.channel!.awaitMessageComponent({
                filter: (i: Discord.Interaction) =>
                    i.user.id === interaction.user.id && i.isMessageComponent() && i.message.id === m.id,
                time: 300000
            })) as
                | Discord.ButtonInteraction
                | Discord.ChannelSelectMenuInteraction
                | Discord.StringSelectMenuInteraction;
        } catch (e) {
            closed = true;
            break;
        }
        if (i.isButton()) {
            switch (i.customId) {
                case "edit": {
                    await i.showModal(
                        new ModalBuilder()
                            .setCustomId("modal")
                            .setTitle(`Options for ${i.customId}`)
                            .addComponents(
                                new ActionRowBuilder<TextInputBuilder>().addComponents(
                                    new TextInputBuilder()
                                        .setCustomId("title")
                                        .setLabel("Title")
                                        .setMaxLength(256)
                                        .setRequired(false)
                                        .setStyle(TextInputStyle.Short)
                                        .setValue(data.title ?? "")
                                ),
                                new ActionRowBuilder<TextInputBuilder>().addComponents(
                                    new TextInputBuilder()
                                        .setCustomId("description")
                                        .setLabel("The text to display below the title")
                                        .setMaxLength(4000)
                                        .setRequired(false)
                                        .setStyle(TextInputStyle.Paragraph)
                                        .setValue(data.description ?? "")
                                )
                            )
                    );
                    await interaction.editReply({
                        embeds: [
                            new EmojiEmbed()
                                .setTitle("Button Editor")
                                .setDescription("Modal opened. If you can't see it, click back and try again.")
                                .setStatus("Success")
                                .setEmoji("GUILD.TICKET.OPEN")
                        ],
                        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,
                            interaction.user
                        )) as Discord.ModalSubmitInteraction | null;
                    } catch (e) {
                        closed = true;
                        continue;
                    }
                    if (!out || out.isButton()) continue;
                    data.title =
                        out.fields.getTextInputValue("title").length === 0
                            ? null
                            : out.fields.getTextInputValue("title");
                    data.description =
                        out.fields.getTextInputValue("description").length === 0
                            ? null
                            : out.fields.getTextInputValue("description");
                    break;
                }
                case "send": {
                    await i.deferUpdate();
                    const channel = interaction.guild!.channels.cache.get(data.channel!) as Discord.TextChannel;
                    const messageData: MessageCreateOptions = {};
                    for (const button of data.buttons) {
                        messageData.components = [
                            new ActionRowBuilder<ButtonBuilder>().addComponents(
                                new ButtonBuilder()
                                    .setCustomId(button)
                                    .setLabel(buttonNames[button]!)
                                    .setStyle(ButtonStyle.Primary)
                            )
                        ];
                    }
                    if (data.title || data.description || data.color) {
                        const e = new EmojiEmbed();
                        if (data.title) e.setTitle(data.title);
                        if (data.description) e.setDescription(data.description);
                        if (data.color) e.setColor(data.color);
                        messageData.embeds = [e];
                    }
                    await channel.send(messageData);
                    break;
                }
            }
        } else if (i.isStringSelectMenu()) {
            try {
                await i.deferUpdate();
            } catch (err) {
                console.log(err);
            }
            switch (i.customId) {
                case "preset": {
                    const chosen = presetButtons[parseInt(i.values[0]!)]!;
                    const newColor = colors[chosen.color!]!;
                    data = _.assign(data, chosen, { color: newColor });
                    break;
                }
                case "color": {
                    data.color = colors[i.values[0]!]!;
                    break;
                }
                case "button": {
                    data.buttons = i.values;
                    break;
                }
            }
        } else {
            await i.deferUpdate();
            data.channel = i.values[0]!;
        }
    } while (!closed);
    await interaction.deleteReply();
};

export const check = (interaction: CommandInteraction, _partial: boolean = false) => {
    const member = interaction.member as Discord.GuildMember;
    if (!member.permissions.has("ManageMessages"))
        return "You must have the *Manage Messages* permission to use this command";
    return true;
};
