import { LoadingEmbed } from './../../utils/defaultEmbeds.js';
import type { HistorySchema } from "../../utils/database.js";
import Discord, {
    CommandInteraction,
    GuildMember,
    Interaction,
    Message,
    ActionRowBuilder,
    ButtonBuilder,
    MessageComponentInteraction,
    ModalSubmitInteraction,
    ButtonStyle,
    StringSelectMenuInteraction,
    TextInputStyle,
    APIMessageComponentEmoji
} from "discord.js";
import { SlashCommandSubcommandBuilder, StringSelectMenuOptionBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import client from "../../utils/client.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
import pageIndicator from "../../utils/createPageIndicator.js";

const command = (builder: SlashCommandSubcommandBuilder) =>
    builder
        .setName("info")
        .setDescription("Shows moderator information about a user")
        .addUserOption((option) =>
            option.setName("user").setDescription("The user to get information about").setRequired(true)
        );

const types: Record<string, { emoji: string; text: string }> = {
    warn: { emoji: "PUNISH.WARN.YELLOW", text: "Warned" },
    mute: { emoji: "PUNISH.MUTE.YELLOW", text: "Muted" },
    unmute: { emoji: "PUNISH.MUTE.GREEN", text: "Unmuted" },
    join: { emoji: "MEMBER.JOIN", text: "Joined" },
    leave: { emoji: "MEMBER.LEAVE", text: "Left" },
    kick: { emoji: "MEMBER.KICK", text: "Kicked" },
    softban: { emoji: "PUNISH.SOFTBAN", text: "Softbanned" },
    ban: { emoji: "MEMBER.BAN", text: "Banned" },
    unban: { emoji: "MEMBER.UNBAN", text: "Unbanned" },
    purge: { emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared" },
    nickname: { emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed" }
};

function historyToString(history: HistorySchema) {
    if (!Object.keys(types).includes(history.type)) throw new Error("Invalid history type");
    let s = `${getEmojiByName(types[history.type]!.emoji)} ${history.amount ? history.amount + " " : ""}${
        types[history.type]!.text
    } on <t:${Math.round(history.occurredAt.getTime() / 1000)}:F>`;
    if (history.moderator) {
        s += ` by <@${history.moderator}>`;
    }
    if (history.reason) {
        s += `\n**Reason:**\n> ${history.reason}`;
    }
    if (history.before) {
        s += `\n**Before:**\n> ${history.before}`;
    }
    if (history.after) {
        s += `\n**After:**\n> ${history.after}`;
    }
    return s + "\n";
}

class TimelineSection {
    name: string = "";
    content: { data: HistorySchema; rendered: string }[] = [];

    addContent = (content: { data: HistorySchema; rendered: string }) => {
        this.content.push(content);
        return this;
    };
    contentLength = () => {
        return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0);
    };
    generateName = () => {
        const first = Math.round(this.content[0]!.data.occurredAt.getTime() / 1000);
        const last = Math.round(this.content[this.content.length - 1]!.data.occurredAt.getTime() / 1000);
        if (first === last) {
            return (this.name = `<t:${first}:F>`);
        }
        return (this.name = `<t:${first}:F> - <t:${last}:F>`);
    };
}

const monthNames = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
];

async function showHistory(member: Discord.GuildMember, interaction: CommandInteraction) {
    let currentYear = new Date().getFullYear();
    let pageIndex: number | null = null;
    let history, current: TimelineSection;
    history = await client.database.history.read(member.guild.id, member.id, currentYear);
    history = history
        .sort(
            (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
                b.occurredAt.getTime() - a.occurredAt.getTime()
        )
        .reverse();
    let m: Message;
    let refresh = false;
    let filteredTypes: string[] = [];
    let openFilterPane = false;
    let timedOut = false;
    let showHistorySelected = false;
    while (!timedOut && !showHistorySelected) {
        if (refresh) {
            history = await client.database.history.read(member.guild.id, member.id, currentYear);
            history = history
                .sort(
                    (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
                        b.occurredAt.getTime() - a.occurredAt.getTime()
                )
                .reverse();
            if (openFilterPane) {
                let tempFilteredTypes = filteredTypes;
                if (filteredTypes.length === 0) {
                    tempFilteredTypes = Object.keys(types);
                }
                history = history.filter((h: { type: string }) => tempFilteredTypes.includes(h.type));
            }
            refresh = false;
        }
        const groups: TimelineSection[] = [];
        if (history.length > 0) {
            current = new TimelineSection();
            history.forEach((event: HistorySchema) => {
                if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
                    groups.push(current);
                    current.generateName();
                    current = new TimelineSection();
                }
                current.addContent({
                    data: event,
                    rendered: historyToString(event)
                });
            });
            current.generateName();
            groups.push(current);
            if (pageIndex === null) {
                pageIndex = groups.length - 1;
            }
        }
        if (pageIndex === null) pageIndex = 0;
        let components: (ActionRowBuilder<Discord.StringSelectMenuBuilder> | ActionRowBuilder<ButtonBuilder>)[] = []
        if (openFilterPane) components = components.concat([
            new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents(
                new Discord.StringSelectMenuBuilder().setOptions(
                    ...Object.entries(types).map(([key, value]) => new StringSelectMenuOptionBuilder()
                        .setLabel(value.text)
                        .setValue(key)
                        .setDefault(filteredTypes.includes(key))
                        .setEmoji(client.emojis.resolve(getEmojiByName(value.emoji, "id"))! as APIMessageComponentEmoji)
                    )
                )
                .setMinValues(1)
                .setMaxValues(Object.keys(types).length)
                .setCustomId("filter")
                .setPlaceholder("Select events to show")
            )
        ])
        components = components.concat([new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
            new ButtonBuilder()
                .setCustomId("prevYear")
                .setLabel((currentYear - 1).toString())
                .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                .setStyle(ButtonStyle.Secondary),
            new ButtonBuilder()
                .setCustomId("prevPage")
                .setLabel("Previous page")
                .setStyle(ButtonStyle.Primary),
            new ButtonBuilder().setCustomId("today").setLabel("Today").setStyle(ButtonStyle.Primary),
            new ButtonBuilder()
                .setCustomId("nextPage")
                .setLabel("Next page")
                .setStyle(ButtonStyle.Primary)
                .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
            new ButtonBuilder()
                .setCustomId("nextYear")
                .setLabel((currentYear + 1).toString())
                .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
                .setStyle(ButtonStyle.Secondary)
                .setDisabled(currentYear === new Date().getFullYear())
        ])])
        components = components.concat([new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
            new ButtonBuilder()
                .setLabel("Mod notes")
                .setCustomId("modNotes")
                .setStyle(ButtonStyle.Primary)
                .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
            new ButtonBuilder()
                .setLabel("Filter")
                .setCustomId("openFilter")
                .setStyle(openFilterPane ? ButtonStyle.Success : ButtonStyle.Primary)
                .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
        ])])

        const end =
            "\n\nJanuary " +
            currentYear.toString() +
            pageIndicator(Math.max(groups.length, 1), groups.length === 0 ? 1 : pageIndex) +
            (currentYear === new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December") +
            " " +
            currentYear.toString();
        if (groups.length > 0) {
            const toRender = groups[Math.min(pageIndex, groups.length - 1)]!;
            m = await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("MEMBER.JOIN")
                        .setTitle("Moderation history for " + member.user.username)
                        .setDescription(
                            `**${toRender.name}**\n\n` + toRender.content.map((c) => c.rendered).join("\n") + end
                        )
                        .setStatus("Success")
                        .setFooter({
                            text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : "No filters selected"
                        })
                ],
                components: components
            });
        } else {
            m = await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("MEMBER.JOIN")
                        .setTitle("Moderation history for " + member.user.username)
                        .setDescription(`**${currentYear}**\n\n*No events*`)
                        .setStatus("Success")
                        .setFooter({
                            text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : "No filters selected"
                        })
                ],
                components: components
            })
        }
        let i: MessageComponentInteraction;
        try {
            i = await m.awaitMessageComponent({ time: 300000 });
        } catch (e) {
            interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setEmoji("MEMBER.JOIN")
                        .setTitle("Moderation history for " + member.user.username)
                        .setDescription(m.embeds[0]!.description!)
                        .setStatus("Danger")
                        .setFooter({ text: "Message timed out" })
                ]
            });
            timedOut = true;
            continue;
        }
        i.deferUpdate();
        if (i.customId === "filter") {
            filteredTypes = (i as StringSelectMenuInteraction).values;
            pageIndex = null;
            refresh = true;
        }
        if (i.customId === "prevYear") {
            currentYear--;
            pageIndex = null;
            refresh = true;
        }
        if (i.customId === "nextYear") {
            currentYear++;
            pageIndex = null;
            refresh = true;
        }
        if (i.customId === "prevPage") {
            pageIndex!--;
            if (pageIndex! < 0) {
                pageIndex = null;
                currentYear--;
                refresh = true;
            }
        }
        if (i.customId === "nextPage") {
            pageIndex!++;
            if (pageIndex! >= groups.length) {
                pageIndex = 0;
                currentYear++;
                refresh = true;
            }
        }
        if (i.customId === "today") {
            currentYear = new Date().getFullYear();
            pageIndex = null;
            refresh = true;
        }
        if (i.customId === "modNotes") {
            showHistorySelected = true;
        }
        if (i.customId === "openFilter") {
            openFilterPane = !openFilterPane;
            refresh = true;
        }
    }
    return timedOut ? 0 : 1;
}

const callback = async (interaction: CommandInteraction): Promise<unknown> => {
    let m: Message;
    const member = interaction.options.getMember("user") as Discord.GuildMember;
    await interaction.reply({
        embeds: LoadingEmbed,
        ephemeral: true,
        fetchReply: true
    });
    let note;
    let firstLoad = true;
    let timedOut = false;
    while (!timedOut) {
        note = await client.database.notes.read(member.guild.id, member.id);
        if (firstLoad && !note) { await showHistory(member, interaction); }
        firstLoad = false;
        m = (await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setEmoji("MEMBER.JOIN")
                    .setTitle("Mod notes for " + member.user.username)
                    .setDescription(note ? note : "*No note set*")
                    .setStatus("Success")
            ],
            components: [
                new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
                    new ButtonBuilder()
                        .setLabel(`${note ? "Modify" : "Create"} note`)
                        .setStyle(ButtonStyle.Primary)
                        .setCustomId("modify")
                        .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
                    new ButtonBuilder()
                        .setLabel("Moderation history")
                        .setStyle(ButtonStyle.Primary)
                        .setCustomId("history")
                        .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
                ])
            ]
        })) as Message;
        let i: MessageComponentInteraction;
        try {
            i = await m.awaitMessageComponent({ time: 300000 });
        } catch (e) {
            timedOut = true;
            continue;
        }
        if (i.customId === "modify") {
            await i.showModal(
                new Discord.ModalBuilder()
                    .setCustomId("modal")
                    .setTitle("Editing moderator note")
                    .addComponents(
                        new ActionRowBuilder<Discord.TextInputBuilder>().addComponents(
                            new Discord.TextInputBuilder()
                                .setCustomId("note")
                                .setLabel("Note")
                                .setMaxLength(4000)
                                .setRequired(false)
                                .setStyle(TextInputStyle.Paragraph)
                                .setValue(note ? note : " ")
                        )
                    )
            );
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Mod notes for " + member.user.username)
                        .setDescription("Modal opened. If you can't see it, click back and try again.")
                        .setStatus("Success")
                        .setEmoji("GUILD.TICKET.OPEN")
                ],
                components: [
                    new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
                        new ButtonBuilder()
                            .setLabel("Back")
                            .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                            .setStyle(ButtonStyle.Primary)
                            .setCustomId("back")
                    ])
                ]
            });
            let out;
            try {
                out = await modalInteractionCollector(
                    m,
                    (m: Interaction) =>
                        (m as MessageComponentInteraction | ModalSubmitInteraction).channelId === interaction.channelId,
                    (m) => m.customId === "modify"
                );
            } catch (e) {
                timedOut = true;
                continue;
            }
            if (out === null) {
                continue;
            } else if (out instanceof ModalSubmitInteraction) {
                let toAdd = out.fields.getTextInputValue("note") || null;
                if (toAdd === " ") toAdd = null;
                if (toAdd) toAdd = toAdd.trim();
                await client.database.notes.create(member.guild.id, member.id, toAdd);
            } else {
                continue;
            }
        } else if (i.customId === "history") {
            i.deferUpdate();
            if (!(await showHistory(member, interaction))) return;
        }
    }
};

const check = (interaction: CommandInteraction) => {
    const member = interaction.member as GuildMember;
    if (!member.permissions.has("ModerateMembers"))
        throw new Error("You do not have the *Moderate Members* permission");
    return true;
};

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