import {
    ActionRowBuilder,
    APIMessageComponentEmoji,
    ButtonBuilder,
    ButtonStyle,
    ChannelSelectMenuBuilder,
    ChannelType,
    CommandInteraction,
    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 && (data.title ?? data.description ?? data.buttons.length)))
        );

        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(0)
                .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: `The embed will be sent in ${channelName} | Click the button below to edit the embed` });

        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;
                    let components: ActionRowBuilder<ButtonBuilder>[] = []
                    let embeds: EmojiEmbed[] = [];
                    for (const button of data.buttons) {
                        components = [
                            new ActionRowBuilder<ButtonBuilder>().addComponents(
                                new ButtonBuilder()
                                    .setCustomId(button)
                                    .setLabel(buttonNames[button]!)
                                    .setStyle(ButtonStyle.Primary)
                            )
                        ];
                    }
                    if (data.title || data.description) {
                        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);
                        embeds = [e]
                    }
                    await channel.send({ embeds, components })
                    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;
};
