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.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 });
    let issueNumber: number | null = null;
    try {
        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"]
        });
        issueNumber = issue.data.number;
    } catch (_e) {
        console.log("Could not connect to GitHub");
    }
    const disabled = issueNumber ? false : true;
    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: `${issueNumber ? issueNumber : "Could not connect to GitHub"}` })
        ],
        components: [
            new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
                new ButtonBuilder().setCustomId("accept:Suggestion").setLabel("Accept").setStyle(ButtonStyle.Success).setDisabled(disabled),
                new ButtonBuilder().setCustomId("deny:Suggestion").setLabel("Deny").setStyle(ButtonStyle.Danger).setDisabled(disabled),
                new ButtonBuilder().setCustomId("close:Suggestion").setLabel("Close").setStyle(ButtonStyle.Secondary).setDisabled(disabled),
                new ButtonBuilder()
                    .setCustomId("implemented:Suggestion")
                    .setLabel("Implemented")
                    .setStyle(ButtonStyle.Secondary)
                    .setDisabled(disabled),
                new ButtonBuilder()
                    .setLabel(`Open Issue #${issueNumber ? issueNumber : "0"}`)
                    .setStyle(ButtonStyle.Link)
                    .setURL(`https://github.com/ClicksMinutePer/Nucleus/issues/${issueNumber}`)
                    .setDisabled(disabled)
            ),
            new Discord.ActionRowBuilder<ButtonBuilder>().addComponents(
                new ButtonBuilder().setCustomId("lock:Comment").setLabel("Lock").setStyle(ButtonStyle.Danger).setDisabled(disabled),
                new ButtonBuilder().setCustomId("spam:Suggestion").setLabel("Mark as Spam").setStyle(ButtonStyle.Danger).setDisabled(disabled)
            )
        ]
    });
    await interaction.editReply({
        embeds: [
            new EmojiEmbed()
                .setEmoji("ICONS.ADD")
                .setTitle("Suggest")
                .setDescription("Your suggestion was sent successfully")
                .setStatus("Success")
        ],
        components: []
    });
};

export { command };
export { callback };
