import { Message, MessageButton } from "discord.js";
import EmojiEmbed from '../utils/generateEmojiEmbed.js'
import { MessageActionRow, MessageSelectMenu } from 'discord.js';
import getEmojiByName from "../utils/getEmojiByName.js";
import client from "../utils/client.js";
import { LoadingEmbed } from "../utils/defaultEmbeds.js";

export async function callback(interaction) {
    let 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("CONTROL.BLOCKCROSS")
    ], 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 or try again later.")
        .setStatus("Danger")
        .setEmoji("CONTROL.BLOCKCROSS")
    ], ephemeral: true})
    await interaction.reply({embeds: LoadingEmbed, ephemeral: true})
    let m;
    if (config.roleMenu.allowWebUI) {
        let code = ""
        let length = 5
        let itt = 0
        const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        while (true) {
            itt += 1
            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 += 1
                continue;
            }
            break;
        }
        client.roleMenu[code] = {
            guild: interaction.guild.id,
            guildName: interaction.guild.name,
            guildIcon: interaction.guild.iconURL({format: "png"}),
            user: interaction.member.user.id,
            username: interaction.member.user.username,
            data: config.roleMenu.options,
            interaction: interaction
        };
        let up = true
        try {
            let status = await fetch(client.config.baseUrl).then(res => res.status);
            if (status !== 200) up = false
        } catch { up = false }
        m = await interaction.editReply({
            embeds: [new EmojiEmbed()
                .setTitle("Roles")
                .setDescription("Select how to choose your roles")
                .setStatus("Success")
                .setEmoji("GUILD.GREEN")
            ], components: [new MessageActionRow().addComponents([
                new MessageButton()
                    .setLabel("Online")
                    .setStyle("LINK")
                    .setDisabled(!up)
                    .setURL(`${client.config.baseUrl}/nucleus/rolemenu?code=${code}`),
                new MessageButton()
                    .setLabel("Manual")
                    .setStyle("PRIMARY")
                    .setCustomId("manual")
            ])]
        })
    }
    let component;
    try { component = await (m as Message).awaitMessageComponent({time: 300000});
    } catch (e) { return }
    component.deferUpdate()
    let rolesToAdd = []
    for (let i = 0; i < config.roleMenu.options.length; i++) {
        let object = config.roleMenu.options[i];
        let m = await interaction.editReply({
            embeds: [
                new EmojiEmbed()
                    .setTitle("Roles")
                    .setEmoji("GUILD.GREEN")
                    .setDescription(`**${object.name}**` + (object.description ? `\n${object.description}` : ``) +
                        `\n\nSelect ${object.min}` + (object.min !== object.max ? ` to ${object.max}` : ``) + ` role${object.max === 1 ? '' : 's'} to add.`)
                    .setStatus("Success")
                    .setFooter({text: `Step ${i + 1}/${config.roleMenu.options.length}`})
            ],
            components: [
                new MessageActionRow().addComponents([
                    new MessageButton()
                        .setLabel("Cancel")
                        .setStyle("DANGER")
                        .setCustomId("cancel")
                        .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
                    ].concat(object.min === 0 ? [
                        new MessageButton()
                            .setLabel("Skip")
                            .setStyle("SECONDARY")
                            .setCustomId("skip")
                            .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
                        ] : []))
            ].concat([new MessageActionRow().addComponents([new MessageSelectMenu()
                .setPlaceholder(`${object.name}`)
                .setCustomId("rolemenu")
                .setMinValues(object.min)
                .setMaxValues(object.max)
                .setOptions(object.options.map(o => { return {label: o.name, description: o.description, value: o.role} }))
            ])])
        });
        let component;
        try {
            component = await (m as Message).awaitMessageComponent({time: 300000});
        } catch (e) {
            return
        }
        component.deferUpdate()
        if (component.customId === "rolemenu") {
            rolesToAdd = rolesToAdd.concat(component.values)
        } else if (component.customId === "cancel") {
            return await interaction.editReply({embeds: [new EmojiEmbed()
                .setTitle("Roles")
                .setDescription("Cancelled. No changes were made.")
                .setStatus("Danger")
                .setEmoji("GUILD.RED")
            ], components: []})
        }
    }
    let rolesToRemove = config.roleMenu.options.map(o => o.options.map(o => o.role)).flat()
    let memberRoles = interaction.member.roles.cache.map(r => r.id)
    rolesToRemove = rolesToRemove.filter(r => memberRoles.includes(r)).filter(r => !rolesToAdd.includes(r))
    rolesToAdd = rolesToAdd.filter(r => !memberRoles.includes(r))
    try {
        await interaction.member.roles.remove(rolesToRemove)
        await interaction.member.roles.add(rolesToAdd)
    } 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 added. You may close this message.")
        .setStatus("Success")
        .setEmoji("GUILD.GREEN")
    ], components: []})
    return
}
