import { unknownServerIcon } from "./../utils/defaults.js";
import {
    ButtonBuilder,
    CommandInteraction,
    ButtonStyle,
    ButtonInteraction,
    StringSelectMenuOptionBuilder,
    StringSelectMenuBuilder,
    GuildMemberRoleManager,
    Role,
    ContextMenuCommandInteraction
} from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import { ActionRowBuilder } from "discord.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import client from "../utils/client.js";
import { LoadingEmbed } from "../utils/defaults.js";
import type { GuildConfig } from "../utils/database.js";
import { roleException } from "../utils/createTemporaryStorage.js";
import addPlural from "../utils/plurals.js";
import createPageIndicator from "../utils/createPageIndicator.js";

export interface RoleMenuSchema {
    guild: string;
    guildName: string;
    guildIcon: string;
    user: string;
    username: string;
    data: GuildConfig["roleMenu"]["options"];
    interaction: CommandInteraction | ButtonInteraction | ContextMenuCommandInteraction;
}

interface ObjectSchema {
    name: string;
    description: string;
    min: number;
    max: number;
    options: {
        name: string;
        description: string | null;
        role: string;
    }[];
}

export const configToDropdown = (
    placeholder: string,
    currentPageData: ObjectSchema,
    selectedRoles?: string[]
): ActionRowBuilder<StringSelectMenuBuilder> => {
    return new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
        new StringSelectMenuBuilder()
            .setCustomId("roles")
            .setPlaceholder(placeholder)
            .setMinValues(currentPageData.min)
            .setMaxValues(currentPageData.max)
            .addOptions(
                currentPageData.options.map((option: { name: string; description: string | null; role: string }) => {
                    const builder = new StringSelectMenuOptionBuilder()
                        .setLabel(option.name)
                        .setValue(option.role)
                        .setDefault(selectedRoles ? selectedRoles.includes(option.role) : false);
                    if (option.description) builder.setDescription(option.description);
                    return builder;
                })
            )
    );
};

export async function callback(interaction: CommandInteraction | ButtonInteraction) {
    if (!interaction.member) return;
    if (!interaction.guild) return;
    const config = await client.database.guilds.read(interaction.guild.id);
    if (!config.roleMenu.enabled) {
        return await interaction.reply({
            embeds: [
                new EmojiEmbed()
                    .setTitle("Roles")
                    .setDescription(
                        "Self roles are currently disabled. Please contact a staff member or try again later."
                    )
                    .setStatus("Danger")
                    .setEmoji("GUILD.RED")
            ],
            ephemeral: true
        });
    }
    if (config.roleMenu.options.length === 0)
        return await interaction.reply({
            embeds: [
                new EmojiEmbed()
                    .setTitle("Roles")
                    .setDescription(
                        "There are no roles available. Please contact a staff member if you believe this is a mistake."
                    )
                    .setStatus("Danger")
                    .setEmoji("GUILD.RED")
            ],
            ephemeral: true
        });
    const m = await interaction.reply({ embeds: LoadingEmbed, ephemeral: true, fetchReply: true });
    if (config.roleMenu.allowWebUI) {
        // TODO: Make rolemenu web ui
        const loginMethods: { webUI: boolean } = {
            webUI: false
        };
        try {
            const status = await fetch(client.config.baseUrl).then((res) => res.status);
            if (status !== 200) loginMethods.webUI = false;
        } catch (e) {
            loginMethods.webUI = false;
        }
        if (Object.values(loginMethods).some((i) => i)) {
            let code = "";
            if (loginMethods.webUI) {
                let length = 5;
                let itt = 0;
                const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
                let valid = false;
                while (!valid) {
                    itt++;
                    code = "";
                    for (let i = 0; i < length; i++) {
                        code += chars.charAt(Math.floor(Math.random() * chars.length));
                    }
                    if (code in client.roleMenu) continue;
                    if (itt > 1000) {
                        itt = 0;
                        length++;
                        continue;
                    }
                    valid = true;
                }
                client.roleMenu[code] = {
                    guild: interaction.guild.id,
                    guildName: interaction.guild.name,
                    guildIcon: interaction.guild.iconURL({ extension: "png" }) ?? unknownServerIcon,
                    user: interaction.member!.user.id,
                    username: interaction.member!.user.username,
                    data: config.roleMenu.options,
                    interaction: interaction as CommandInteraction | ButtonInteraction
                };
            }
            await interaction.editReply({
                embeds: [
                    new EmojiEmbed()
                        .setTitle("Roles")
                        .setDescription("Select how to choose your roles")
                        .setStatus("Success")
                        .setEmoji("GUILD.GREEN")
                ],
                components: [
                    new ActionRowBuilder<ButtonBuilder>().addComponents([
                        new ButtonBuilder()
                            .setLabel("Online")
                            .setStyle(ButtonStyle.Link)
                            .setDisabled(!loginMethods.webUI)
                            .setURL(`${client.config.baseUrl}nucleus/rolemenu?code=${code}`),
                        new ButtonBuilder().setLabel("In Discord").setStyle(ButtonStyle.Primary).setCustomId("discord")
                    ])
                ]
            });
            let component;
            try {
                component = await m.awaitMessageComponent({
                    time: 300000,
                    filter: (i) => {
                        return (
                            i.user.id === interaction.user.id &&
                            i.channelId === interaction.channelId &&
                            i.message.id === m.id
                        );
                    }
                });
            } catch (e) {
                console.log(e);
                return;
            }
            component.deferUpdate();
        }
    }

    const options = config.roleMenu.options;
    const selectedRoles: string[][] = [];
    const maxPage = options.length;
    const completedPages: boolean[] = options.map((option) => option.min === 0);
    for (let i = 0; i < maxPage; i++) {
        selectedRoles.push([]);
    }

    let page = 0;
    let complete = completedPages.every((page) => page);
    let done = false;

    while (!(complete && done)) {
        const currentPageData = options[page]!;
        const embed = new EmojiEmbed()
            .setTitle("Roles")
            .setDescription(
                `**${currentPageData.name}**\n` +
                    `> ${currentPageData.description}\n\n` +
                    (currentPageData.min === currentPageData.max
                        ? `Select ${addPlural(currentPageData.min, "role")}`
                        : `Select between ${currentPageData.min} and ${currentPageData.max} roles then press next`) +
                    "\n\n" +
                    createPageIndicator(maxPage, page)
            )
            .setStatus("Success")
            .setEmoji("GUILD.GREEN");
        const components = [
            new ActionRowBuilder<ButtonBuilder>().addComponents(
                new ButtonBuilder()
                    .setStyle(ButtonStyle.Secondary)
                    .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
                    .setCustomId("back")
                    .setDisabled(page === 0),
                new ButtonBuilder()
                    .setStyle(ButtonStyle.Secondary)
                    .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
                    .setCustomId("next")
                    .setDisabled(page === maxPage - 1),
                new ButtonBuilder()
                    .setStyle(ButtonStyle.Success)
                    .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
                    .setCustomId("done")
                    .setDisabled(!complete)
            ),
            configToDropdown("Select...", currentPageData, selectedRoles[page])
        ];
        await interaction.editReply({
            embeds: [embed],
            components: components
        });
        let component;
        try {
            component = await m.awaitMessageComponent({
                time: 300000,
                filter: (i) => {
                    return (
                        i.user.id === interaction.user.id &&
                        i.channel!.id === interaction.channel!.id &&
                        i.message.id === m.id
                    );
                }
            });
        } catch (e) {
            console.log(e);
            return;
        }
        component.deferUpdate();
        if (component.customId === "back") {
            page = Math.max(0, page - 1);
        } else if (component.customId === "next") {
            page = Math.min(maxPage - 1, page + 1);
        } else if (component.customId === "done") {
            done = true;
        } else if (component.customId === "roles" && component.isStringSelectMenu()) {
            selectedRoles[page] = component.values;
            completedPages[page] = true;
            page = Math.min(maxPage - 1, page + 1);
        }
        complete = completedPages.every((page) => page);
    }

    const fullRoleList: string[] = selectedRoles.flat();

    const memberRoles = (interaction.member.roles as GuildMemberRoleManager).cache.map((r) => r.id); // IDs
    let rolesToRemove = config.roleMenu.options.map((o) => o.options.map((o) => o.role)).flat(); // IDs
    rolesToRemove = rolesToRemove.filter((r) => memberRoles.includes(r)).filter((r) => !fullRoleList.includes(r)); // IDs
    let roleObjectsToAdd = fullRoleList
        .map((r) => interaction.guild!.roles.cache.get(r)) // Role objects
        .filter((r) => r !== undefined) as Role[];
    roleObjectsToAdd = roleObjectsToAdd.filter((r) => !memberRoles.includes(r.id)); // Role objects
    try {
        roleException(interaction.guild.id, interaction.user.id);
        await (interaction.member.roles as GuildMemberRoleManager).remove(rolesToRemove);
        await (interaction.member.roles as GuildMemberRoleManager).add(roleObjectsToAdd);
    } catch (e) {
        return await interaction.reply({
            embeds: [
                new EmojiEmbed()
                    .setTitle("Roles")
                    .setDescription(
                        "Something went wrong and your roles were not added. Please contact a staff member or try again later."
                    )
                    .setStatus("Danger")
                    .setEmoji("GUILD.RED")
            ],
            components: []
        });
    }
    await interaction.editReply({
        embeds: [
            new EmojiEmbed()
                .setTitle("Roles")
                .setDescription("Roles have been updated")
                .setStatus("Success")
                .setEmoji("GUILD.GREEN")
        ],
        components: []
    });
    return;
}
