import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, {
    ActionRowBuilder,
    ButtonBuilder,
    ButtonStyle,
    CommandInteraction,
    ModalBuilder,
    TextInputBuilder,
    TextInputStyle
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
import config from "../../config/main.js";
import _ from "lodash";

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder.setName("suggest").setDescription("Sends a suggestion to the developers");

const callback = async (interaction: CommandInteraction): Promise<void> => {
    await interaction.guild?.members.fetch(interaction.member!.user.id);
    await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
    let closed = false;
    let suggestionTitle: string | null = null;
    let suggestionDesc: string | null = null;
    do {
        const modal = new ModalBuilder()
            .setTitle("Suggestion")
            .setComponents(
                new ActionRowBuilder<TextInputBuilder>().addComponents(
                    new TextInputBuilder()
                        .setLabel("Suggestion Title")
                        .setRequired(false)
                        .setStyle(TextInputStyle.Short)
                        .setCustomId("suggestionTitle")
                        .setPlaceholder("Summarize your suggestion in 1 sentence...")
                        .setMaxLength(256)
                ),
                new ActionRowBuilder<TextInputBuilder>().addComponents(
                    new TextInputBuilder()
                        .setLabel("Suggestion Description")
                        .setCustomId("suggestionDesc")
                        .setStyle(TextInputStyle.Paragraph)
                        .setRequired(true)
                        .setPlaceholder("Put the full details of your suggestion here...")
                        .setMinLength(50)
                )
            );
        const o: { suggestionDesc?: string; suggestionTitle?: string } = {};
        if (suggestionTitle) {
            o.suggestionTitle = suggestionTitle;
            modal.components[0]!.components[0]!.setValue(suggestionTitle);
        }
        if (suggestionDesc) {
            o.suggestionDesc = suggestionDesc;
            modal.components[1]!.components[0]!.setValue(suggestionDesc);
        }
        const confirmation = await new confirmationMessage(interaction)
            .setEmoji("ICONS.ADD")
            .setTitle("Suggest")
            .setDescription(
                suggestionDesc
                    ? `Are you sure you want to send this suggestion?\n\n**Title ${
                          suggestionTitle ? "" : "(*Placeholder*)"
                      }:**\n> ${
                          suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`
                      }\n\n**Suggestion:**\n> ${suggestionDesc}`
                    : "Please enter your suggestion below."
            )
            .addModal("Edit Suggestion", "ICONS.EDIT", "editSuggestion", _.cloneDeep(o), modal)
            .setColor("Success")
            .setInverted(true)
            .setFailedMessage("Your suggestion was deleted", "Success", "ICONS.ADD")
            .send(true);
        if (confirmation.modals?.[0] && !_.isEqual(confirmation.modals[0].values, o)) {
            suggestionTitle = confirmation.modals[0].values["suggestionTitle"] as string | null;
            suggestionDesc = confirmation.modals[0].values["suggestionDesc"] as string | null;
            continue;
        }
        if (confirmation.cancelled || confirmation.success === false) {
            closed = true;
            return;
        }
        if (confirmation.success) {
            closed = true;
        }
    } while (!closed);
    if (!suggestionDesc) return;
    suggestionTitle = suggestionTitle ? suggestionTitle : `${suggestionDesc.substring(0, 70)}`;
    const channel = client.channels.cache.get(config.suggestionChannel) as Discord.TextChannel;
    const m = await channel.send({ embeds: LoadingEmbed });
    const issue = await client.GitHub.rest.issues.create({
        owner: "ClicksMinutePer",
        repo: "Nucleus",
        title: suggestionTitle,
        body: `Linked Suggestion in Private Developer Channel: [Message](${
            m.url
        })\n\n**Suggestion:**\n> ${suggestionDesc
            .replaceAll("@", "@<!-- -->")
            .replaceAll("/issues", "/issues<!-- -->")
            .replaceAll("/pull", "/pull<!-- -->")}\n\n`,
        labels: ["🤖 Auto", "📝 Suggestion"]
    });
    await m.edit({
        embeds: [
            new EmojiEmbed()
                .setEmoji("ICONS.ADD")
                .setTitle(`Suggestion from ${interaction.user.tag} (${interaction.user.id})`)
                .setDescription(`**Suggestion:**\n> ${suggestionDesc}\n\n`)
                .setStatus("Success")
                .setFooter({ text: `${issue.data.number}` })
        ],
        components: [
            new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
                new ButtonBuilder().setCustomId("accept:Suggestion").setLabel("Accept").setStyle(ButtonStyle.Success),
                new ButtonBuilder().setCustomId("deny:Suggestion").setLabel("Deny").setStyle(ButtonStyle.Danger),
                new ButtonBuilder().setCustomId("close:Suggestion").setLabel("Close").setStyle(ButtonStyle.Secondary),
                new ButtonBuilder()
                    .setCustomId("implemented:Suggestion")
                    .setLabel("Implemented")
                    .setStyle(ButtonStyle.Secondary),
                new ButtonBuilder()
                    .setLabel(`Open Issue #${issue.data.number}`)
                    .setStyle(ButtonStyle.Link)
                    .setURL(`https://github.com/ClicksMinutePer/Nucleus/issues/${issue.data.number}`)
            ),
            new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
                new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger),
                new ButtonBuilder().setCustomId("spam:Suggestion").setLabel("Mark as Spam").setStyle(ButtonStyle.Danger)
            )
        ]
    });
    await interaction.editReply({
        embeds: [
            new EmojiEmbed()
                .setEmoji("ICONS.ADD")
                .setTitle("Suggest")
                .setDescription("Your suggestion was sent successfully")
                .setStatus("Success")
        ],
        components: []
    });
};

export { command };
export { callback };
