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,
} from "discord.js";
import type { SlashCommandSubcommandBuilder } 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("about")
        // .setNameLocalizations({"ru": "info", "zh-CN": "history", "zh-TW": "notes", "pt-BR": "flags"})
        .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()
                    .setMinValues(1)
                    .setMaxValues(Object.keys(types).length)
                    .setCustomId("filter")
                    .setPlaceholder("Select events to show")
                    .setOptions(...Object.entries(types).map(([key, value]) => new Discord.StringSelectMenuOptionBuilder()
                        .setLabel(value.text)
                        .setValue(key)
                        .setDefault(filteredTypes.includes(key))
                        // @ts-expect-error
                        .setEmoji(getEmojiByName(value.emoji, "id"))  // FIXME: This gives a type error but is valid
            )))
        ]);
        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 };
