import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import Discord, {
    CommandInteraction,
    GuildChannel,
    Message,
    ActionRowBuilder,
    Component,
    ButtonBuilder,
    MessageComponentInteraction,
    SelectMenuBuilder,
    Role,
    SelectMenuInteraction,
    TextInputComponent,
    ButtonStyle
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { ChannelType } from "discord-api-types/v9";
import client from "../../utils/client.js";
import { toHexInteger, toHexArray, tickets as ticketTypes } from "../../utils/calculate.js";
import { capitalize } from "../../utils/generateKeyValueList.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
import type { GuildConfig } from "../../utils/database.js";

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("tickets")
        .setDescription("Shows settings for tickets | Use no arguments to manage custom types")
        .addStringOption((option) =>
            option
                .setName("enabled")
                .setDescription("If users should be able to create tickets")
                .setRequired(false)
                .addChoices(
                    {name: "Yes", value: "yes"},
                    {name: "No",value:  "no"}
                )
        )
        .addChannelOption((option) =>
            option
                .setName("category")
                .setDescription("The category where tickets are created")
                .addChannelTypes(ChannelType.GuildCategory)
                .setRequired(false)
        )
        .addNumberOption((option) =>
            option
                .setName("maxticketsperuser")
                .setDescription("The maximum amount of tickets a user can create | Default: 5")
                .setRequired(false)
                .setMinValue(1)
        )
        .addRoleOption((option) =>
            option
                .setName("supportrole")
                .setDescription(
                    "This role will have view access to all tickets and will be pinged when a ticket is created"
                )
                .setRequired(false)
        );

const callback = async (interaction: CommandInteraction): Promise<unknown> => {
    if (!interaction.guild) return;
    let m = (await interaction.reply({
        embeds: LoadingEmbed,
        ephemeral: true,
        fetchReply: true
    })) as Message;
    const options = {
        enabled: interaction.options.getString("enabled")?.startsWith("yes") as boolean | null,
        category: interaction.options.getChannel("category"),
        maxtickets: interaction.options.getNumber("maxticketsperuser"),
        supportping: interaction.options.getRole("supportrole")
    };
    if (options.enabled !== null || options.category || options.maxtickets || options.supportping) {
        if (options.category) {
            let channel: GuildChannel | null;
            try {
                channel = await interaction.guild.channels.fetch(options.category.id);
            } catch {
                return await interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setEmoji("CHANNEL.TEXT.DELETE")
                            .setTitle("Tickets > Category")
                            .setDescription("The channel you provided is not a valid category")
                            .setStatus("Danger")
                    ]
                });
            }
            if (!channel) return;
            channel = channel as Discord.CategoryChannel;
            if (channel.guild.id !== interaction.guild.id)
                return interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setTitle("Tickets > Category")
                            .setDescription("You must choose a category in this server")
                            .setStatus("Danger")
                            .setEmoji("CHANNEL.TEXT.DELETE")
                    ]
                });
        }
        if (options.maxtickets) {
            if (options.maxtickets < 1)
                return interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setTitle("Tickets > Max Tickets")
                            .setDescription("You must choose a number greater than 0")
                            .setStatus("Danger")
                            .setEmoji("CHANNEL.TEXT.DELETE")
                    ]
                });
        }
        let role: Role | null;
        if (options.supportping) {
            try {
                role = await interaction.guild.roles.fetch(options.supportping.id);
            } catch {
                return await interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setEmoji("GUILD.ROLE.DELETE")
                            .setTitle("Tickets > Support Ping")
                            .setDescription("The role you provided is not a valid role")
                            .setStatus("Danger")
                    ]
                });
            }
            if (!role) return;
            role = role as Discord.Role;
            if (role.guild.id !== interaction.guild.id)
                return interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setTitle("Tickets > Support Ping")
                            .setDescription("You must choose a role in this server")
                            .setStatus("Danger")
                            .setEmoji("GUILD.ROLE.DELETE")
                    ]
                });
        }

        const confirmation = await new confirmationMessage(interaction)
            .setEmoji("GUILD.TICKET.ARCHIVED", "GUILD.TICKET.CLOSE")
            .setTitle("Tickets")
            .setDescription(
                (options.category ? `**Category:** ${options.category.name}\n` : "") +
                    (options.maxtickets ? `**Max Tickets:** ${options.maxtickets}\n` : "") +
                    (options.supportping ? `**Support Ping:** ${options.supportping.name}\n` : "") +
                    (options.enabled !== null
                        ? `**Enabled:** ${
                            options.enabled
                                ? `${getEmojiByName("CONTROL.TICK")} Yes`
                                : `${getEmojiByName("CONTROL.CROSS")} No`
                        }\n`
                        : "") +
                    "\nAre you sure you want to apply these settings?"
            )
            .setColor("Warning")
            .setInverted(true)
            .send(true);
        if (confirmation.cancelled) return;
        if (confirmation.success) {
            const toUpdate: Record<string, string | boolean | number> = {};
            if (options.enabled !== null) toUpdate["tickets.enabled"] = options.enabled;
            if (options.category) toUpdate["tickets.category"] = options.category.id;
            if (options.maxtickets) toUpdate["tickets.maxTickets"] = options.maxtickets;
            if (options.supportping) toUpdate["tickets.supportRole"] = options.supportping.id;
            try {
                await client.database.guilds.write(interaction.guild.id, toUpdate);
            } catch (e) {
                return interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setTitle("Tickets")
                            .setDescription("Something went wrong and the staff notifications channel could not be set")
                            .setStatus("Danger")
                            .setEmoji("GUILD.TICKET.DELETE")
                    ],
                    components: []
                });
            }
        } else {
            return interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Tickets")
                        .setDescription("No changes were made")
                        .setStatus("Success")
                        .setEmoji("GUILD.TICKET.OPEN")
                ],
                components: []
            });
        }
    }
    let data = await client.database.guilds.read(interaction.guild.id);
    data.tickets.customTypes = (data.tickets.customTypes || []).filter(
        (value: string, index: number, array: string[]) => array.indexOf(value) === index
    );
    let lastClicked = "";
    let embed: EmojiEmbed;
    data = {
        enabled: data.tickets.enabled,
        category: data.tickets.category,
        maxTickets: data.tickets.maxTickets,
        supportRole: data.tickets.supportRole,
        useCustom: data.tickets.useCustom,
        types: data.tickets.types,
        customTypes: data.tickets.customTypes
    };
    let timedOut = false;
    while (!timedOut) {
        embed = new EmojiEmbed()
            .setTitle("Tickets")
            .setDescription(
                `${data.enabled ? "" : getEmojiByName("TICKETS.REPORT")} **Enabled:** ${
                    data.enabled ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
                }\n` +
                    `${data.category ? "" : getEmojiByName("TICKETS.REPORT")} **Category:** ${
                        data.category ? `<#${data.category}>` : "*None set*"
                    }\n` +
                    `**Max Tickets:** ${data.maxTickets ? data.maxTickets : "*No limit*"}\n` +
                    `**Support Ping:** ${data.supportRole ? `<@&${data.supportRole}>` : "*None set*"}\n\n` +
                    (data.useCustom && data.customTypes === null ? `${getEmojiByName("TICKETS.REPORT")} ` : "") +
                    `${data.useCustom ? "Custom" : "Default"} types in use` +
                    "\n\n" +
                    `${getEmojiByName("TICKETS.REPORT")} *Indicates a setting stopping tickets from being used*`
            )
            .setStatus("Success")
            .setEmoji("GUILD.TICKET.OPEN");
        m = (await interaction.editReply({
            embeds: [embed],
            components: [
                new ActionRowBuilder().addComponents([
                    new ButtonBuilder()
                        .setLabel("Tickets " + (data.enabled ? "enabled" : "disabled"))
                        .setEmoji(getEmojiByName("CONTROL." + (data.enabled ? "TICK" : "CROSS"), "id"))
                        .setStyle(data.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
                        .setCustomId("enabled"),
                    new ButtonBuilder()
                        .setLabel(lastClicked === "cat" ? "Click again to confirm" : "Clear category")
                        .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
                        .setStyle(ButtonStyle.Danger)
                        .setCustomId("clearCategory")
                        .setDisabled(data.category === null),
                    new ButtonBuilder()
                        .setLabel(lastClicked === "max" ? "Click again to confirm" : "Reset max tickets")
                        .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
                        .setStyle(ButtonStyle.Danger)
                        .setCustomId("clearMaxTickets")
                        .setDisabled(data.maxTickets === 5),
                    new ButtonBuilder()
                        .setLabel(lastClicked === "sup" ? "Click again to confirm" : "Clear support ping")
                        .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
                        .setStyle(ButtonStyle.Danger)
                        .setCustomId("clearSupportPing")
                        .setDisabled(data.supportRole === null)
                ]),
                new ActionRowBuilder().addComponents([
                    new ButtonBuilder()
                        .setLabel("Manage types")
                        .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
                        .setStyle(ButtonStyle.Secondary)
                        .setCustomId("manageTypes"),
                    new ButtonBuilder()
                        .setLabel("Add create ticket button")
                        .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
                        .setStyle(ButtonStyle.Primary)
                        .setCustomId("send")
                ])
            ]
        })) as Message;
        let i: MessageComponentInteraction;
        try {
            i = await m.awaitMessageComponent({ time: 300000 });
        } catch (e) {
            timedOut = true;
            continue;
        }
        i.deferUpdate();
        if ((i.component as Component).customId === "clearCategory") {
            if (lastClicked === "cat") {
                lastClicked = "";
                await client.database.guilds.write(interaction.guild.id, null, ["tickets.category"]);
                data.category = undefined;
            } else lastClicked = "cat";
        } else if ((i.component as Component).customId === "clearMaxTickets") {
            if (lastClicked === "max") {
                lastClicked = "";
                await client.database.guilds.write(interaction.guild.id, null, ["tickets.maxTickets"]);
                data.maxTickets = 5;
            } else lastClicked = "max";
        } else if ((i.component as Component).customId === "clearSupportPing") {
            if (lastClicked === "sup") {
                lastClicked = "";
                await client.database.guilds.write(interaction.guild.id, null, ["tickets.supportRole"]);
                data.supportRole = undefined;
            } else lastClicked = "sup";
        } else if ((i.component as Component).customId === "send") {
            const ticketMessages = [
                {
                    label: "Create ticket",
                    description: "Click the button below to create a ticket"
                },
                {
                    label: "Issues, questions or feedback?",
                    description: "Click below to open a ticket and get help from our staff team"
                },
                {
                    label: "Contact Us",
                    description: "Click the button below to speak to us privately"
                }
            ];
            let innerTimedOut = false;
            let templateSelected = false;
            while (!innerTimedOut && !templateSelected) {
                const enabled = data.enabled && data.category !== null;
                await interaction.editReply({
                    embeds: [
                        new EmojiEmbed()
                            .setTitle("Ticket Button")
                            .setDescription("Select a message template to send in this channel")
                            .setFooter({
                                text: enabled
                                    ? ""
                                    : "Tickets are not set up correctly so the button may not work for users. Check the main menu to find which options must be set."
                            })
                            .setStatus(enabled ? "Success" : "Warning")
                            .setEmoji("GUILD.ROLES.CREATE")
                    ],
                    components: [
                        new ActionRowBuilder().addComponents([
                            new SelectMenuBuilder()
                                .setOptions(
                                    ticketMessages.map(
                                        (
                                            t: {
                                                label: string;
                                                description: string;
                                                value?: string;
                                            },
                                            index
                                        ) => {
                                            t.value = index.toString();
                                            return t as {
                                                value: string;
                                                label: string;
                                                description: string;
                                            };
                                        }
                                    )
                                )
                                .setCustomId("template")
                                .setMaxValues(1)
                                .setMinValues(1)
                                .setPlaceholder("Select a message template")
                        ]),
                        new ActionRowBuilder().addComponents([
                            new ButtonBuilder()
                                .setCustomId("back")
                                .setLabel("Back")
                                .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                                .setStyle(ButtonStyle.Danger),
                            new ButtonBuilder().setCustomId("blank").setLabel("Empty").setStyle(ButtonStyle.Secondary),
                            new ButtonBuilder()
                                .setCustomId("custom")
                                .setLabel("Custom")
                                .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
                                .setStyle(ButtonStyle.Primary)
                        ])
                    ]
                });
                let i: MessageComponentInteraction;
                try {
                    i = await m.awaitMessageComponent({ time: 300000 });
                } catch (e) {
                    innerTimedOut = true;
                    continue;
                }
                if ((i.component as Component).customId === "template") {
                    i.deferUpdate();
                    await interaction.channel!.send({
                        embeds: [
                            new EmojiEmbed()
                                .setTitle(ticketMessages[parseInt((i as SelectMenuInteraction).values[0]!)]!.label)
                                .setDescription(
                                    ticketMessages[parseInt((i as SelectMenuInteraction).values[0]!)]!.description
                                )
                                .setStatus("Success")
                                .setEmoji("GUILD.TICKET.OPEN")
                        ],
                        components: [
                            new ActionRowBuilder().addComponents([
                                new ButtonBuilder()
                                    .setLabel("Create Ticket")
                                    .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
                                    .setStyle(ButtonStyle.Success)
                                    .setCustomId("createticket")
                            ])
                        ]
                    });
                    templateSelected = true;
                    continue;
                } else if ((i.component as Component).customId === "blank") {
                    i.deferUpdate();
                    await interaction.channel!.send({
                        components: [
                            new ActionRowBuilder().addComponents([
                                new ButtonBuilder()
                                    .setLabel("Create Ticket")
                                    .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
                                    .setStyle(ButtonStyle.Success)
                                    .setCustomId("createticket")
                            ])
                        ]
                    });
                    templateSelected = true;
                    continue;
                } else if ((i.component as Component).customId === "custom") {
                    await i.showModal(
                        new Discord.Modal()
                            .setCustomId("modal")
                            .setTitle("Enter embed details")
                            .addComponents(
                                new ActionRowBuilder<TextInputComponent>().addComponents(
                                    new TextInputComponent()
                                        .setCustomId("title")
                                        .setLabel("Title")
                                        .setMaxLength(256)
                                        .setRequired(true)
                                        .setStyle("SHORT")
                                ),
                                new ActionRowBuilder<TextInputComponent>().addComponents(
                                    new TextInputComponent()
                                        .setCustomId("description")
                                        .setLabel("Description")
                                        .setMaxLength(4000)
                                        .setRequired(true)
                                        .setStyle("PARAGRAPH")
                                )
                            )
                    );
                    await interaction.editReply({
                        embeds: [
                            new EmojiEmbed()
                                .setTitle("Ticket Button")
                                .setDescription("Modal opened. If you can't see it, click back and try again.")
                                .setStatus("Success")
                                .setEmoji("GUILD.TICKET.OPEN")
                        ],
                        components: [
                            new ActionRowBuilder().addComponents([
                                new ButtonBuilder()
                                    .setLabel("Back")
                                    .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                                    .setStyle(ButtonStyle.Primary)
                                    .setCustomId("back")
                            ])
                        ]
                    });
                    let out;
                    try {
                        out = await modalInteractionCollector(
                            m,
                            (m) => m.channel!.id === interaction.channel!.id,
                            (m) => m.customId === "modify"
                        );
                    } catch (e) {
                        innerTimedOut = true;
                        continue;
                    }
                    if (out.fields) {
                        const title = out.fields.getTextInputValue("title");
                        const description = out.fields.getTextInputValue("description");
                        await interaction.channel.send({
                            embeds: [
                                new EmojiEmbed()
                                    .setTitle(title)
                                    .setDescription(description)
                                    .setStatus("Success")
                                    .setEmoji("GUILD.TICKET.OPEN")
                            ],
                            components: [
                                new ActionRowBuilder().addComponents([
                                    new ButtonBuilder()
                                        .setLabel("Create Ticket")
                                        .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
                                        .setStyle(ButtonStyle.Success)
                                        .setCustomId("createticket")
                                ])
                            ]
                        });
                        templateSelected = true;
                    }
                }
            }
        } else if ((i.component as Component).customId === "enabled") {
            await client.database.guilds.write(interaction.guild.id, {
                "tickets.enabled": !data.enabled
            });
            data.enabled = !data.enabled;
        } else if ((i.component as Component).customId === "manageTypes") {
            data = await manageTypes(interaction, data, m as Message);
        }
    }
    await interaction.editReply({
        embeds: [embed.setFooter({ text: "Message timed out" })],
        components: []
    });
};

async function manageTypes(interaction: CommandInteraction, data: GuildConfig["tickets"], m: Message) {
    let timedOut = false;
    let backPressed = false;
    while (!timedOut && !backPressed) {
        if (data.useCustom) {
            const customTypes = data.customTypes;
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Tickets > Types")
                        .setDescription(
                            "**Custom types enabled**\n\n" +
                                "**Types in use:**\n" +
                                (customTypes !== null ? customTypes.map((t) => `> ${t}`).join("\n") : "*None set*") +
                                "\n\n" +
                                (customTypes === null
                                    ? `${getEmojiByName(
                                          "TICKETS.REPORT"
                                      )} Having no types will disable tickets. Please add at least 1 type or use default types`
                                    : "")
                        )
                        .setStatus("Success")
                        .setEmoji("GUILD.TICKET.OPEN")
                ],
                components: (customTypes
                    ? [
                          new ActionRowBuilder().addComponents([
                              new Discord.SelectMenuBuilder()
                                  .setCustomId("removeTypes")
                                  .setPlaceholder("Select types to remove")
                                  .setMaxValues(customTypes.length)
                                  .setMinValues(1)
                                  .addOptions(
                                      customTypes.map((t) => ({
                                          label: t,
                                          value: t
                                      }))
                                  )
                          ])
                      ]
                    : []
                ).concat([
                    new ActionRowBuilder().addComponents([
                        new ButtonBuilder()
                            .setLabel("Back")
                            .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                            .setStyle(ButtonStyle.Primary)
                            .setCustomId("back"),
                        new ButtonBuilder()
                            .setLabel("Add new type")
                            .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
                            .setStyle(ButtonStyle.Primary)
                            .setCustomId("addType")
                            .setDisabled(customTypes !== null && customTypes.length >= 25),
                        new ButtonBuilder()
                            .setLabel("Switch to default types")
                            .setStyle(ButtonStyle.Secondary)
                            .setCustomId("switchToDefault")
                    ])
                ])
            });
        } else {
            const inUse = toHexArray(data.types, ticketTypes);
            const options = [];
            ticketTypes.forEach((type) => {
                options.push(
                    new SelectMenuOption({
                        label: capitalize(type),
                        value: type,
                        emoji: client.emojis.cache.get(getEmojiByName(`TICKETS.${type.toUpperCase()}`, "id")),
                        default: inUse.includes(type)
                    })
                );
            });
            const selectPane = new ActionRowBuilder().addComponents([
                new Discord.SelectMenuBuilder()
                    .addOptions(options)
                    .setCustomId("types")
                    .setMaxValues(ticketTypes.length)
                    .setMinValues(1)
                    .setPlaceholder("Select types to use")
            ]);
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Tickets > Types")
                        .setDescription(
                            "**Default types enabled**\n\n" +
                                "**Types in use:**\n" +
                                inUse
                                    .map((t) => `> ${getEmojiByName("TICKETS." + t.toUpperCase())} ${capitalize(t)}`)
                                    .join("\n")
                        )
                        .setStatus("Success")
                        .setEmoji("GUILD.TICKET.OPEN")
                ],
                components: [
                    selectPane,
                    new ActionRowBuilder().addComponents([
                        new ButtonBuilder()
                            .setLabel("Back")
                            .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                            .setStyle(ButtonStyle.Primary)
                            .setCustomId("back"),
                        new ButtonBuilder()
                            .setLabel("Switch to custom types")
                            .setStyle(ButtonStyle.Secondary)
                            .setCustomId("switchToCustom")
                    ])
                ]
            });
        }
        let i;
        try {
            i = await m.awaitMessageComponent({ time: 300000 });
        } catch (e) {
            timedOut = true;
            continue;
        }
        if (i.component.customId === "types") {
            i.deferUpdate();
            const types = toHexInteger(i.values, ticketTypes);
            await client.database.guilds.write(interaction.guild.id, {
                "tickets.types": types
            });
            data.types = types;
        } else if (i.component.customId === "removeTypes") {
            i.deferUpdate();
            const types = i.values;
            let customTypes = data.customTypes;
            if (customTypes) {
                customTypes = customTypes.filter((t) => !types.includes(t));
                customTypes = customTypes.length > 0 ? customTypes : null;
                await client.database.guilds.write(interaction.guild.id, {
                    "tickets.customTypes": customTypes
                });
                data.customTypes = customTypes;
            }
        } else if (i.component.customId === "addType") {
            await i.showModal(
                new Discord.Modal()
                    .setCustomId("modal")
                    .setTitle("Enter a name for the new type")
                    .addComponents(
                        new ActionRowBuilder<TextInputComponent>().addComponents(
                            new TextInputComponent()
                                .setCustomId("type")
                                .setLabel("Name")
                                .setMaxLength(100)
                                .setMinLength(1)
                                .setPlaceholder('E.g. "Server Idea"')
                                .setRequired(true)
                                .setStyle("SHORT")
                        )
                    )
            );
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Tickets > Types")
                        .setDescription("Modal opened. If you can't see it, click back and try again.")
                        .setStatus("Success")
                        .setEmoji("GUILD.TICKET.OPEN")
                ],
                components: [
                    new ActionRowBuilder().addComponents([
                        new ButtonBuilder()
                            .setLabel("Back")
                            .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                            .setStyle(ButtonStyle.Primary)
                            .setCustomId("back")
                    ])
                ]
            });
            let out;
            try {
                out = await modalInteractionCollector(
                    m,
                    (m) => m.channel.id === interaction.channel.id,
                    (m) => m.customId === "addType"
                );
            } catch (e) {
                continue;
            }
            if (out.fields) {
                let toAdd = out.fields.getTextInputValue("type");
                if (!toAdd) {
                    continue;
                }
                toAdd = toAdd.substring(0, 80);
                try {
                    await client.database.guilds.append(interaction.guild.id, "tickets.customTypes", toAdd);
                } catch {
                    continue;
                }
                data.customTypes = data.customTypes ?? [];
                if (!data.customTypes.includes(toAdd)) {
                    data.customTypes.push(toAdd);
                }
            } else {
                continue;
            }
        } else if (i.component.customId === "switchToDefault") {
            i.deferUpdate();
            await client.database.guilds.write(interaction.guild.id, { "tickets.useCustom": false }, []);
            data.useCustom = false;
        } else if (i.component.customId === "switchToCustom") {
            i.deferUpdate();
            await client.database.guilds.write(interaction.guild.id, { "tickets.useCustom": true }, []);
            data.useCustom = true;
        } else {
            i.deferUpdate();
            backPressed = true;
        }
    }
    return data;
}

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

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