import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
import Discord, { GuildMember } from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import fetch from "node-fetch";
import { TestString, NSFWCheck } from "./scanners.js";
import createPageIndicator from "../utils/createPageIndicator.js";
import client from "../utils/client.js";

function step(i) {
    return "\n\n" + createPageIndicator(5, i);
}

export default async function(interaction) {
    const verify = client.verify;
    await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true});
    const config = await client.database.guilds.read(interaction.guild.id);
    if ((!config.verify.enabled ) || (!config.verify.role)) return interaction.editReply({embeds: [new EmojiEmbed()
        .setTitle("Verify")
        .setDescription("Verify is not enabled on this server")
        .setFooter({text: interaction.member.permissions.has("MANAGE_GUILD") ? "You can enable it by running /settings verify" : ""})
        .setStatus("Danger")
        .setEmoji("CONTROL.BLOCKCROSS")
    ], ephemeral: true, fetchReply: true});
    if ((interaction.member as GuildMember).roles.cache.has(config.verify.role)) {
        return await interaction.editReply({embeds: [new EmojiEmbed()
            .setTitle("Verify")
            .setDescription(`You already have the <@&${config.verify.role}> role` + step(0))
            .setStatus("Danger")
            .setEmoji("CONTROL.BLOCKCROSS")
        ]});
    }
    await interaction.editReply({embeds: [new EmojiEmbed()
        .setTitle("Verify")
        .setDescription("Checking our servers are up" + step(0))
        .setStatus("Warning")
        .setEmoji("NUCLEUS.LOADING")
    ]});
    try {
        const status = await fetch(client.config.baseUrl).then(res => res.status);
        if (status !== 200) {
            return await interaction.editReply({embeds: [new EmojiEmbed()
                .setTitle("Verify")
                .setDescription("Our servers appear to be down, please try again later" + step(0))
                .setStatus("Danger")
                .setEmoji("CONTROL.BLOCKCROSS")
            ]});
        }
    } catch {
        return await interaction.editReply({embeds: [new EmojiEmbed()
            .setTitle("Verify")
            .setDescription("Our servers appear to be down, please try again later" + step(0))
            .setStatus("Danger")
            .setEmoji("CONTROL.BLOCKCROSS")
        ], components: [new Discord.MessageActionRow().addComponents([
            new Discord.MessageButton()
                .setLabel("Check webpage")
                .setStyle("LINK")
                .setURL(client.config.baseUrl),
            new Discord.MessageButton()
                .setLabel("Support")
                .setStyle("LINK")
                .setURL("https://discord.gg/bPaNnxe")
        ])]});
    }
    if (config.filters.images.NSFW) {
        await interaction.editReply({embeds: [new EmojiEmbed()
            .setTitle("Verify")
            .setDescription("Checking your avatar is safe for work" + step(1))
            .setStatus("Warning")
            .setEmoji("NUCLEUS.LOADING")
        ]});
        if (await NSFWCheck((interaction.member as GuildMember).user.avatarURL({format: "png"}))) {
            return await interaction.editReply({embeds: [new EmojiEmbed()
                .setTitle("Verify")
                .setDescription("Your avatar was detected as NSFW, which we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake" + step(1))
                .setStatus("Danger")
                .setEmoji("CONTROL.BLOCKCROSS")
            ]});
        }
    }
    if (config.filters.wordFilter) {
        await interaction.editReply({embeds: [new EmojiEmbed()
            .setTitle("Verify")
            .setDescription("Checking your name is allowed" + step(2))
            .setStatus("Warning")
            .setEmoji("NUCLEUS.LOADING")
        ]});
        if (TestString((interaction.member as Discord.GuildMember).displayName, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict) !== null) {
            return await interaction.editReply({embeds: [new EmojiEmbed()
                .setTitle("Verify")
                .setDescription("Your name contained a word we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake" + step(2))
                .setStatus("Danger")
                .setEmoji("CONTROL.BLOCKCROSS")
            ]});
        }
    }
    await interaction.editReply({embeds: [new EmojiEmbed()
        .setTitle("Verify")
        .setDescription("One moment..." + step(3))
        .setStatus("Warning")
        .setEmoji("NUCLEUS.LOADING")
    ]});
    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 verify) continue;
        if (itt > 1000) {
            itt = 0;
            length += 1;
            continue;
        }
        break;
    }
    verify[code] = {
        uID: interaction.member.user.id,
        gID: interaction.guild.id,
        rID: config.verify.role,
        rName: (await interaction.guild.roles.fetch(config.verify.role)).name,
        uName: interaction.member.user.username,
        gName: interaction.guild.name,
        gIcon: interaction.guild.iconURL({format: "png"}),
        interaction: interaction
    };
    await interaction.editReply({embeds: [new EmojiEmbed()
        .setTitle("Verify")
        .setDescription("Looking good!\nClick the button below to get verified" + step(4))
        .setStatus("Success")
        .setEmoji("MEMBER.JOIN")
    ], components: [new Discord.MessageActionRow().addComponents([new Discord.MessageButton()
        .setLabel("Verify")
        .setStyle("LINK")
        .setURL(`${client.config.baseUrl}nucleus/verify?code=${code}`)
    ])]});
}
