import { callback as roleMenu } from "../actions/roleMenu.js";
import verify from "../reflex/verify.js";
import create from "../actions/tickets/create.js";
import close from "../actions/tickets/delete.js";
import createTranscript from "../premium/createTranscript.js";

import {
    ActionRowBuilder,
    ButtonBuilder,
    ButtonInteraction,
    ButtonStyle,
    Interaction,
    InteractionEditReplyOptions,
    ModalBuilder,
    ModalSubmitInteraction,
    TextInputBuilder,
    TextInputStyle
} from "discord.js";
import type { NucleusClient } from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";

import { callback as banCallback, check as banCheck } from "../commands/mod/ban.js";
import { callback as kickCallback, check as kickCheck } from "../commands/mod/kick.js";
import { callback as muteCallback, check as muteCheck } from "../commands/mod/mute.js";
import { callback as nicknameCallback, check as nicknameCheck } from "../commands/mod/nick.js";
import { callback as warnCallback, check as warnCheck } from "../commands/mod/warn.js";
import { callback as logDetailsCallback } from "../actions/logs/showDetails.js";
import client from "../utils/client.js";

export const event = "interactionCreate";

async function errorMessage(interaction: ButtonInteraction, message: string) {
    await interaction.reply({
        embeds: [new EmojiEmbed().setDescription(message).setStatus("Danger")],
        ephemeral: true,
        components: []
    });
}

async function interactionCreate(interaction: Interaction) {
    if (interaction.isButton()) {
        if (interaction.customId.endsWith(":Suggestion")) {
            const value =
                interaction.customId.startsWith("accept") || interaction.customId.startsWith("implement")
                    ? true
                    : false;
            return await modifySuggestion(interaction, value);
        }
        if (interaction.customId === "log:message.edit") {
            await interaction.channel?.messages.fetch({ message: interaction.message.id, force: true });
            const attachment = interaction.message.embeds[0]?.image ?? interaction.message.attachments.first();
            if (!attachment) return;
            const attachmentData = await (await fetch(attachment.url)).text();
            const decoded = atob(attachmentData);
            const json = (
                JSON.parse(decoded) as { data: { count: number; value: string; added?: boolean; removed?: boolean }[] }
            ).data;
            // "Before" is everything where added is false
            // "After" is everything where removed is false
            const before: string = json
                .filter((d) => !d.added)
                .map((d) => d.value)
                .join("");
            const after: string = json
                .filter((d) => !d.removed)
                .map((d) => d.value)
                .join("");
            const { renderDateFooter } = client.logger;
            await interaction.reply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Before")
                        .setDescription(before)
                        .setStatus("Danger")
                        .setEmoji("ICONS.OPP.ADD"),
                    new EmojiEmbed()
                        .setTitle("After")
                        .setDescription(after)
                        .setStatus("Success")
                        .setEmoji("ICONS.ADD")
                        .setFooter({ text: `Edited at ${renderDateFooter(interaction.message.createdTimestamp!)}` }) // Created timestamp of the log is when the edit was made
                ],
                ephemeral: true
            });
        } else if (interaction.customId === "log:message.delete") {
            await interaction.channel?.messages.fetch({ message: interaction.message.id, force: true });
            const attachment = interaction.message.embeds[0]?.image ?? interaction.message.attachments.first();
            if (!attachment) return;
            const attachmentData = await (await fetch(attachment.url)).text();
            const decoded = atob(attachmentData);
            const json = JSON.parse(decoded) as { data: string };
            await interaction.reply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Message")
                        .setDescription(json.data)
                        .setStatus("Danger")
                        .setEmoji("MESSAGE.DELETE")
                        .setFooter({ text: `Deleted at ${client.logger.renderDateFooter(Date.now())}` })
                ],
                ephemeral: true
            });
        }
        switch (interaction.customId) {
            case "rolemenu": {
                return await roleMenu(interaction);
            }
            case "verifybutton": {
                return await verify(interaction);
            }
            case "createticket": {
                return await create(interaction);
            }
            case "closeticket": {
                return await close(interaction);
            }
            case "createtranscript": {
                return await createTranscript(interaction);
            }
            case "log:showDetails": {
                return await logDetailsCallback(interaction);
            }
        }
        // Mod actions
        if (interaction.customId.startsWith("mod:")) {
            const action = interaction.customId.split(":")[1];
            const memberId = interaction.customId.split(":")[2];
            const member = await interaction.guild?.members.fetch(memberId!);
            switch (action) {
                case "kick": {
                    const check = kickCheck(interaction, false, member);
                    if (check !== true) return await errorMessage(interaction, check!);
                    return await kickCallback(interaction, member);
                }
                case "ban": {
                    const check = banCheck(interaction, false, member);
                    if (check !== true) return await errorMessage(interaction, check!);
                    return await banCallback(interaction, member);
                }
                case "mute": {
                    const check = muteCheck(interaction, false, member);
                    if (check !== true) return await errorMessage(interaction, check!);
                    return await muteCallback(interaction, member);
                }
                case "nickname": {
                    const check = nicknameCheck(interaction, false, member);
                    if (check !== true) return await errorMessage(interaction, check || "Something went wrong");
                    return await nicknameCallback(interaction, member);
                }
                case "warn": {
                    const check = warnCheck(interaction, false, member);
                    if (check !== true) return await errorMessage(interaction, check!);
                    return await warnCallback(interaction, member);
                }
            }
        }
    }
}

const getReason = async (buttonInteraction: ButtonInteraction, prompt: string) => {
    const modal = new ModalBuilder()
        .addComponents(
            new ActionRowBuilder<TextInputBuilder>().addComponents(
                new TextInputBuilder().setStyle(TextInputStyle.Paragraph).setLabel(prompt).setCustomId("typed")
            )
        )
        .setTitle("Reason")
        .setCustomId("modal");
    await buttonInteraction.showModal(modal);
    let out: ModalSubmitInteraction;
    try {
        out = await buttonInteraction.awaitModalSubmit({
            filter: (i) => i.customId === "modal" && i.user.id === buttonInteraction.user.id,
            time: 300000
        });
    } catch {
        return null;
    }
    await out.deferUpdate();
    return out.fields.getTextInputValue("typed");
};

async function modifySuggestion(interaction: ButtonInteraction, accept: boolean) {
    const message = interaction.message;
    await message.fetch();
    if (message.embeds.length === 0) return;
    const embed = message.embeds[0]!;
    const issueNum = embed.footer!.text;
    if (!issueNum) return;
    const issue = {
        owner: "ClicksMinutePer",
        repo: "Nucleus",
        issue_number: parseInt(issueNum)
    };
    let name = "Unknown";
    const components: InteractionEditReplyOptions["components"] = [];
    switch (interaction.customId) {
        case "accept:Suggestion": {
            name = "Accepted";
            await interaction.deferUpdate();
            await client.GitHub.rest.issues.createComment({
                ...issue,
                body: "Suggestion accepted by " + interaction.user.tag
            });
            components.push(
                new ActionRowBuilder<ButtonBuilder>().addComponents(
                    new ButtonBuilder()
                        .setCustomId("close:Suggestion")
                        .setLabel("Close")
                        .setStyle(ButtonStyle.Secondary),
                    new ButtonBuilder()
                        .setCustomId("implemented:Suggestion")
                        .setLabel("Implemented")
                        .setStyle(ButtonStyle.Secondary)
                )
            );
            break;
        }
        case "deny:Suggestion": {
            name = "Denied";
            const reason = await getReason(interaction, "Reason for denial");
            await client.GitHub.rest.issues.createComment({
                ...issue,
                body: "Suggestion denied by " + interaction.user.tag + " for reason:\n>" + reason
            });
            await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "not_planned" });
            // await client.GitHub.rest.issues.lock({...issue, lock_reason: "resolved"})
            components.push(
                new ActionRowBuilder<ButtonBuilder>().addComponents(
                    new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger)
                )
            );
            break;
        }
        case "close:Suggestion": {
            name = "Closed";
            const reason = await getReason(interaction, "Reason for closing");
            await client.GitHub.rest.issues.createComment({
                ...issue,
                body: "Suggestion closed by " + interaction.user.tag + " for reason:\n>" + reason
            });
            await client.GitHub.rest.issues.update({ ...issue, state: "closed" });
            // await client.GitHub.rest.issues.lock({...issue})
            components.push(
                new ActionRowBuilder<ButtonBuilder>().addComponents(
                    new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger)
                )
            );
            break;
        }
        case "implement:Suggestion": {
            name = "Implemented";
            await interaction.deferUpdate();
            await client.GitHub.rest.issues.createComment({ ...issue, body: "Suggestion implemented" });
            await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "completed" });
            await client.GitHub.rest.issues.lock({ ...issue, lock_reason: "resolved" });
            break;
        }
        case "lock:Suggestion": {
            name = "Locked";
            await interaction.deferUpdate();
            await client.GitHub.rest.issues.lock({ ...issue });
            break;
        }
        case "spam:Suggestion": {
            name = "Marked as Spam";
            await interaction.deferUpdate();
            await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "not_planned" });
            await client.GitHub.rest.issues.lock({ ...issue, lock_reason: "spam" });
            break;
        }
    }

    const newcolor = accept ? "Success" : "Danger";
    const newEmoji = accept ? "ICONS.ADD" : "ICONS.OPP.ADD";

    const newEmbed = new EmojiEmbed()
        .setEmoji(newEmoji)
        .setTitle(embed!.title!.replace(/.+> /, ""))
        .setDescription(embed!.description!)
        .setFields({
            name: name + " by",
            value: interaction.user.tag
        })
        .setStatus(newcolor)
        .setFooter(embed!.footer);

    await interaction.editReply({
        embeds: [newEmbed],
        components: components
    });
}

export async function callback(_client: NucleusClient, interaction: Interaction) {
    await interactionCreate(interaction);
}
