// Configuration
const config = require('./config');
// Driver SQL
const Sequelize = require('sequelize');
const { Op } = require("sequelize");
// API externe
const express = require('express')
const app = express()
var XMLHttpRequest = require('xhr2');
// Couleurs de la console
var colors = require('colors');

// API discord
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');

// Moment JS
var moment = require('moment');

// Schedule
const schedule = require('node-schedule');

////////////////////////////////////////////////////////////////
// MODELES DES TABLES
////////////////////////////////////////////////////////////////

// Connexion à la base de données
const sequelize = new Sequelize(config.get("BDD_NAME"), config.get("BDD_USER"), config.get("BDD_PASSWORD"), {
    host: config.get("BDD_HOST"),
    dialect: 'mariadb',
    logging: false,
});

// Paramètres du bot
const botSettings = sequelize.define('discord_settings', {
    name: { type: Sequelize.STRING(128), primaryKey: true },
    value: Sequelize.STRING(512),
}, {
    timestamps: false
});

// Entrées et sorties des membres
const entries = sequelize.define('discord_entries', {
    id: { type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true },
    memberId: Sequelize.BIGINT(255),
    isJoin: Sequelize.BOOLEAN,
    date: Sequelize.DATE,
}, {
    timestamps: false
});

// Paramètres des membres
const memberSettings = sequelize.define('discord_memberSettings', {
    memberId: { type: Sequelize.BIGINT(255), primaryKey: true },
    name: { type: Sequelize.STRING(128), primaryKey: true },
    value: Sequelize.STRING(512),
}, {
    timestamps: false
});

// Paramètres des joueurs MC
const minecraftPlayerSetting = sequelize.define('site_userSetting', {
    uuid: { type: Sequelize.STRING(36), primaryKey: true },
    name: { type: Sequelize.STRING(128), primaryKey: true },
    value: Sequelize.TEXT,
}, {
    timestamps: false,
    freezeTableName: true
});

// Codes de liaison du serveur MC
const mcLinkCode = sequelize.define('site_linkCode', {
    uuid: { type: Sequelize.STRING(36), primaryKey: true },
    code: { type: Sequelize.STRING(8), unique: true },
    time: { type: 'TIMESTAMP', defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), allowNull: false },
    used: { type: Sequelize.BOOLEAN, defaultValue: false },
}, {
    timestamps: false,
    freezeTableName: true
});

////////////////////////////////////////////////////////////////

const commands = [{
    name: 'ping',
    description: 'Répond avec pong!'
},
{
    name: 'setanniv',
    description: 'Permet de définir ta date d\'anniversaire (usage unique).',
    options: [{
        name: "date", // no uppercase as well
        description: "Date au format DD/MM/YYYY - 31/12/2001",
        type: 3,
        required: true
    }]
},
{
    name: 'delanniv',
    description: '[Admin] Supprime la date d\'anniversaire d\'un membre.',
    options: [{
        name: "membre", // no uppercase as well
        description: "Membre à supprimer la date d'anniversaire.",
        type: 6,
        required: true
    }]
},
{
    name: 'linkmc',
    description: 'Te permet de lier ton compte Minecraft au serveur Discord.',
    options: [{
        name: "code", // no uppercase as well
        description: "Code généré par la commande /getlinkcode.",
        type: 3,
        required: true
    }]
}];

////////////////////////////////////////////////////////////////
// INITIALISATION DES COMMANDES ET CONNEXION À LA BASE DE DONNÉES
////////////////////////////////////////////////////////////////
const rest = new REST({ version: '9' }).setToken(config.get("DISCORD_BOT_TOKEN"));

(async () => {
    console.log('[' + 'INFO'.yellow + '] Connexion à la base de donnée...'.brightWhite);
    try {
        await sequelize.authenticate();
        console.log('[' + 'SUCCES'.brightGreen + '] Connexion à la base de donnée réussie.'.brightWhite);
        await initialiseDatabaseTables(); // On va initialiser les tables de la base de donnée

        try {
            console.log('[' + 'INFO'.yellow + '] Actualisation des commandes...'.brightWhite);
            //console.log(JSON.stringify(commands));
            await rest.put(
                Routes.applicationGuildCommands(config.get("CLIENT_ID"), config.get("GUILD_ID")),
                { body: commands },
            );

            console.log('[' + 'SUCCES'.brightGreen + '] Toutes les commandes ont été actualisées.');
        } catch (error) {
            console.error('[' + 'ERREUR'.brightRed + '] Erreur lors de l\'actualisation des commandes:'.brightWhite + error);
        }
    } catch (error) {
        console.log('[' + 'ERREUR'.brightRed + '] Erreur lors de la connexion à la base de donnée:'.brightWhite);
        console.log('[' + 'DEBUG'.yellow + '] '.brightWhite + config.get("BDD_USER") + ":" + config.get("BDD_PASSWORD") + "@" + config.get("BDD_HOST") + " db:" + config.get("BDD_NAME") + '\n');
        console.error(error);
    }

})();

async function initialiseDatabaseTables() {
    console.log('[' + 'INFO'.yellow + '] Initialisation des tables...'.brightWhite);
    try {
        // On synchronise les modèles de sequlize
        await botSettings.sync();
        await entries.sync();
        await memberSettings.sync();
        await minecraftPlayerSetting.sync();
        await mcLinkCode.sync();

        // Basiquement on regarde si l'entrée existe, puis on agit en conséquence
        let token = await botSettings.findOne({ where: { name: "token" } });
        if (token == null) {
            // INSERT si elle n'existe pas
            console.log('[' + 'INSERT'.brightMagenta + '] Insertion de token'.brightWhite);
            let token = botSettings.create({
                name: "token",
                value: config.get("DISCORD_BOT_TOKEN")
            });
        } else {
            // UPDATE si différente
            if (token.value != config.get("DISCORD_BOT_TOKEN")) {
                token.update({ value: config.get("DISCORD_BOT_TOKEN") })
                    .then(updatedRecord => {
                        console.log('[' + 'UPDATE'.brightMagenta + '] Mise à jour du token dans la base de donnée'.brightWhite);
                    }).catch(err => {
                        console.log('[' + 'ERREUR'.brightRed + '] Erreur lors de la màj de token dans la base de donnée: '.brightWhite + '\n');
                        throw new Error(err);
                    });
            }
        }

        // Et c'est pareil à chaque fois
        let clientId = await botSettings.findOne({ where: { name: "clientId" } });
        if (clientId == null) {
            console.log('[' + 'INSERT'.brightMagenta + '] Insertion de clientId'.brightWhite);
            let clientId = botSettings.create({
                name: "clientId",
                value: config.get("CLIENT_ID")
            });
        } else {
            if (clientId.value != config.get("CLIENT_ID")) {
                clientId.update({ value: config.get("CLIENT_ID") })
                    .then(updatedRecord => {
                        console.log('[' + 'UPDATE'.brightMagenta + '] Mise à jour du clientId dans la base de donnée'.brightWhite);
                    }).catch(err => {
                        console.log('[' + 'ERREUR'.brightRed + '] Erreur lors de la màj de clientId dans la base de donnée: '.brightWhite + '\n');
                        throw new Error(err);
                    });
            }
        }

        let guildId = await botSettings.findOne({ where: { name: "guildId" } });
        if (guildId == null) {
            console.log('[' + 'INSERT'.brightMagenta + '] Insertion de guildId'.brightWhite);
            let guildId = botSettings.create({
                name: "guildId",
                value: config.get("GUILD_ID")
            });
        } else {
            if (guildId.value != config.get("GUILD_ID")) {
                guildId.update({ value: config.get("GUILD_ID") })
                    .then(updatedRecord => {
                        console.log('[' + 'UPDATE'.brightMagenta + '] Mise à jour du guildId dans la base de donnée'.brightWhite);
                    }).catch(err => {
                        console.log('[' + 'ERREUR'.brightRed + '] Erreur lors de la màj de guildId dans la base de donnée: '.brightWhite + '\n');
                        throw new Error(err);
                    });
            }
        }

        console.log('[' + 'SUCCES'.brightGreen + '] Tables initialisées avec succès.'.brightWhite);
    } catch (error) {
        console.error('[' + 'ERREUR'.brightRed + '] Erreur lors de l\'initialisation des tables:'.brightWhite + '\n', error);
    }

}

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// CONSOLE
////////////////////////////////////////////////////////////////

// Console Input/Output
var readline = require('readline');

var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// Ce code est a améliorer, je l'ai vulgairement recopié d'un ancien bot (lui même pas très bien conçu)
var recursiveAsyncReadLine = function () {
    rl.question('Commande: ', function (answer) {
        //if (answer == 'exit')
        //  return rl.close();
        const args = answer.match(/(".*?"|[^"\s]+)+(?=\s*|\s*$)/g);
        const command = args.shift().toLowerCase();

        switch (command) {
            case "say":
                if (!args[0] || !args[1])
                    console.log('\n' + '[' + 'ERREUR'.brightRed + "] Tu n'as pas mis d'arguments :p" + '\n' + '[' + 'INFO'.yellow + "] Usage: say <Numéro du canal> <\"Texte\">");
                else {
                    var message = args[1].substring(1, args[1].length - 1);
                    client.channels.cache.get(args[0]).send(message);
                    console.log('\n' + '[' + 'SUCCES'.brightGreen + '] Le message a été envoyé dans le canal n°' + args[0]);
                }
                break;

            default:
                console.log('\n' + "Commande inconnue. :p");
                break;
        }

        recursiveAsyncReadLine(); //Calling this function again to ask new question
    });
};

recursiveAsyncReadLine(); //we have to actually start our recursion somehow

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// BOT DISCORD
////////////////////////////////////////////////////////////////
// require the needed discord.js classes
const { Client, GatewayIntentBits, MessageActionRow, MessageButton, WebhookClient } = require('discord.js');
const { verify } = require('crypto');

// create a new Discord client
const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.GuildMembers,
        GatewayIntentBits.DirectMessages
    ]
})
var mcChatWebhook, devMcChatWebhook;

client.on("ready", async function () {
    console.log('\n' + "SL-Projects Bot".brightCyan);
    console.log("");
    console.log("Bot démarré".brightGreen);

    var guild = client.guilds.cache.get(config.get("GUILD_ID"));
    var memberCount = guild.memberCount.toLocaleString();
    console.log('\n' + "Nous sommes " + memberCount + " membres.");
    client.user.setActivity("Regarde " + memberCount + " membres");

    checkAnniv();

    verifyMcChatWebhook();
});

// Actions lorsqu'un membre rejoins ou part
client.on('guildMemberAdd', async (member) => {
    let guild = client.guilds.cache.get(config.get("GUILD_ID"));
    var memberCount = guild.memberCount.toLocaleString();

    console.log('\n' + "Nouveau membre - " + member.user.username + " - " + memberCount + " membres");
    member.guild.channels.cache.get(config.get("CANAL_LOG")).send("Nouveau membre - " + member.user.username + " - " + memberCount + " membres");
    client.user.setActivity("Regarde " + memberCount + " membres");

    var currentdate = new Date();
    var datetime = currentdate.getFullYear() + "-"
        + (currentdate.getMonth() + 1) + "-"
        + currentdate.getDate() + " "
        + (currentdate.getHours() + 1) + ":"
        + currentdate.getMinutes() + ":"
        + currentdate.getSeconds();

    await entries.create({
        id: null,
        memberId: member.user.id,
        isJoin: 1,
        date: datetime,
    });
});
client.on('guildMemberRemove', async (member) => {
    let guild = client.guilds.cache.get(config.get("GUILD_ID"));
    var memberCount = guild.memberCount.toLocaleString();

    console.log('\n' + "Un membre a quitté le serveur - " + member.user.username + " - " + memberCount + " membres");
    member.guild.channels.cache.get(config.get("CANAL_LOG")).send("Un membre a quitté le serveur - " + member.user.username + " - " + memberCount + " membres");
    client.user.setActivity("Regarde " + memberCount + " membres");

    var currentdate = new Date();
    var datetime = currentdate.getFullYear() + "-"
        + (currentdate.getMonth() + 1) + "-"
        + currentdate.getDate() + " "
        + (currentdate.getHours() + 1) + ":"
        + currentdate.getMinutes() + ":"
        + currentdate.getSeconds();

    await entries.create({
        id: null,
        memberId: member.user.id,
        isJoin: 0,
        date: datetime,
    });
});

// Lorsqu'un message est envoyé
client.on('messageCreate', async message => {
    // On va regarder si le message vient du canal de tchat du serveur MC
    if (message.channel.id == config.get("CANAL_CHAT_MC") && !message.author.bot) {
        var playerName = message.author.username;
        var messageContent = message.content;

        // On va vérifier si l'utilisateur a associé son compte discord avec le serveur MC
        var memberAccountAssoc = await minecraftPlayerSetting.findOne({
            where: {
                name: 'discordAccountId',
                value: message.author.id
            }
        });

        if (memberAccountAssoc != null) {
            // L'utilisateur a bien associé son compte discord avec le serveur MC
            let userMcUsername = await minecraftPlayerSetting.findOne({
                where: {
                    uuid: memberAccountAssoc.uuid,
                    name: 'playerName'
                }
            });
            if(userMcUsername != null) {
                playerName = userMcUsername.value;
            }
        }

        // On encode ça en JSON
        var jsonEncodedMessage = JSON.stringify({
            "message": messageContent,
            "playerName": playerName
        });

        // Maintenant on va appeler le serveur pour envoyer le message
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", "http://node.sl-projects.com:" + config.get("PORT_MSG_SRVMC") + "/discordMsg/" + encodeURIComponent(jsonEncodedMessage), true);
        xmlHttp.send();
    }
});



// Commandes
client.on('interactionCreate', async interaction => {
    if (interaction.isCommand()) {
        console.log('[' + 'COMMANDE'.brightMagenta + '] '.brightWhite + interaction.user.username.brightBlue + ' a lancé la commande '.brightWhite + interaction.commandName.yellow);
        if (interaction.commandName === 'ping') {
            await interaction.reply('Pong!');
        } else if (interaction.commandName === 'setanniv') {
            // Je check si le membre a déjà enregistré sa date d'anniversaire
            let userAnniv = await memberSettings.findOne({
                where: {
                    memberId: interaction.user.id,
                    name: 'birthday'
                }
            });
            // S'il ne l'a pas déjà fait
            if (userAnniv == null) {
                // On va checker que ce qu'il a envoyé est bien une date valide
                let memberBirthday = moment(interaction.options.getString('date'), "DD/MM/YYYY");
                if (isNaN(memberBirthday)) {
                    console.log('\n' + '[' + 'ERREUR'.brightRed + "] Date illisible: " + interaction.options.getString('date'));
                    await interaction.reply('J\'ai du mal à lire la date que tu m\'as donné. Est-elle bien dans ce format **DD/MM/YYYY**? :thinking:');
                } else {
                    try {
                        memberBirthday = memberBirthday.toDate();
                        console.log('[' + 'INSERT'.brightMagenta + '] '.brightWhite + interaction.user.username.brightBlue + " a renseigné sa date d'anniversaire. ".brightWhite + interaction.options.getString('date').yellow);
                        var dd = memberBirthday.getDate();
                        var mm = memberBirthday.getMonth() + 1;

                        var yyyy = memberBirthday.getFullYear();
                        if (dd < 10) {
                            dd = '0' + dd;
                        }
                        if (mm < 10) {
                            mm = '0' + mm;
                        }
                        let birthday = mm + '/' + dd + '/' + yyyy;
                        let insetMemberBirthday = memberSettings.create({
                            memberId: interaction.user.id,
                            name: "birthday",
                            value: birthday
                        });
                        await interaction.reply({ content: 'Je m\'en souviendrai. :thumbup:', ephemeral: true });
                        checkAnniv();
                    } catch (error) {
                        console.error('[' + 'ERREUR'.brightRed + '] Erreur lors de l\'insertion de la date d\'anniversaire: '.brightWhite + '\n', error);
                        await interaction.reply("J'ai eu un petit problème pour enregistrer ta date d'anniversaire, re-essaie plus-tard. :p");
                    }
                }
            } else {
                await interaction.reply('Tu ne peux pas redéfinir ta date d\'anniversaire. Demande au staff si besoin. :p');
            }
        } else if (interaction.commandName === 'delanniv') {
            // On check les perms
            if (interaction.member.roles.cache.has(config.get("ROLE_ANNIV"))) {
                try {
                    console.log('\n' + '[' + 'DELETE'.brightMagenta + "] Suppression de la date d'anniversaire de " + interaction.options.getMember('membre'));
                    await memberSettings.destroy({
                        where: {
                            name: "birthday",
                            memberId: interaction.options.getMember('membre').id
                        }
                    });
                } catch (error) {
                    console.error('[' + 'ERREUR'.brightRed + '] Erreur lors de la supression de la date d\'anniversaire: '.brightWhite + '\n', error);
                    await interaction.reply("J'ai eu un petit problème pour supprimer la date d'anniversaire, re-essaie plus-tard. :p");
                }

                await interaction.reply({ content: 'La date d\'anniversaire de <@' + interaction.options.getMember('membre') + '> a été supprimée.', ephemeral: true });
                checkAnniv();
            } else {
                await interaction.reply({ content: "Tu n'as pas le droit d'exécuter cette commande. :p", ephemeral: true });
            }

        } else if (interaction.commandName === 'linkmc') {
            console.log('[' + 'INFO'.yellow + '] L\'utilisateur '.brightWhite + interaction.user.username.brightBlue + " a demandé une association de son compte Minecraft avec le code ".brightWhite + interaction.options.getString('code').yellow);
            // On va vérifier si le membre a déjà associé son compte minecraft
            let memberAccountAssoc = await minecraftPlayerSetting.findOne({
                where: {
                    name: 'discordAccountId',
                    value: interaction.user.id
                }
            });

            if (memberAccountAssoc == null) {
                // Il ne l'a pas déjà associé 
                // On va donc checker la validité du code
                let code = interaction.options.getString('code');

                // On va le chercher dans la bdd
                let isCodeValid = await mcLinkCode.findOne({
                    where: {
                        code: code,
                        used: false
                    }
                });

                if (isCodeValid != null) {
                    // Le code est valide
                    // On va le mettre dans la bdd
                    await minecraftPlayerSetting.create({
                        name: 'discordAccountId',
                        value: interaction.user.id,
                        uuid: isCodeValid.uuid
                    });

                    // On va mettre à jour le code
                    await mcLinkCode.update({
                        used: true
                    }, {
                        where: {
                            code: code
                        }
                    });

                    // On va récupérer le pseudo du joueur pour la réponse
                    let playerName = await minecraftPlayerSetting.findOne({
                        where: {
                            uuid: isCodeValid.uuid,
                            name: 'playerName'
                        }
                    });

                    // On va envoyer le message
                    await interaction.reply({ content: 'Ton compte a été associé avec le compte Minecraft de **' + playerName.value + '** !', ephemeral: true });
                } else {
                    // Le code n'est pas valide
                    await interaction.reply({ content: 'Le code que tu as entré est invalide. :p', ephemeral: true });
                }
            } else {
                // Il l'a déjà associé
                await interaction.reply({ content: 'Tu as déjà associé ton compte minecraft avec le serveur Discord. :thinking:', ephemeral: true });
            }
        }
    }
});


async function checkAnniv() {
    console.log('[' + 'INFO'.yellow + '] Vérification des anniversaires.'.brightWhite);

    let today = new Date();
    var dd = today.getDate();
    var mm = today.getMonth() + 1;

    var yyyy = today.getFullYear();
    if (dd < 10) {
        dd = '0' + dd;
    }
    if (mm < 10) {
        mm = '0' + mm;
    }
    today = mm + '/' + dd;

    let { count, rows } = await memberSettings.findAndCountAll({
        where: {
            name: "birthday",
            value: {
                [Op.like]: today + '%'
            }
        }
    });

    const guild = client.guilds.cache.get(config.get("GUILD_ID"));
    //console.log(guild);

    var membersWithAnnivRole = await guild.roles.cache.get(config.get("ROLE_ANNIV")).members;
    //console.log(membersWithAnnivRole);

    // On va vérifier que c'est bien l'anniv des membres ayant le rôle. :p
    for await (var memberWithAnnivRole of membersWithAnnivRole) {

        var isMemberBirthday = false;
        for await (const member of rows) {
            if (memberWithAnnivRole[0] === member.memberId.toString()) {
                isMemberBirthday = true;
            }
        }
        if (!isMemberBirthday) {
            console.log('[' + 'INFO'.yellow + '] Suppression du rôle anniversaire pour '.brightWhite + memberWithAnnivRole[1].user.username);
            memberWithAnnivRole[1].roles.remove(config.get("ROLE_ANNIV")).catch(console.error);
        }
    }
    console.log('[' + 'SUCCES'.brightGreen + '] C\'est l\'anniversaire de ' + count + ' personne(s).');

    for await (var member of rows) {
        let memberFetch = await guild.members.fetch(member.memberId.toString());
        //console.log(memberFetch);
        if (memberFetch) {
            console.log(" 🎂 " + memberFetch.user.username);
            if (!memberFetch.roles.cache.has(config.get("ROLE_ANNIV"))) {
                let annivRole = await memberFetch.guild.roles.cache.find(role => role.id === config.get("ROLE_ANNIV"));
                if (annivRole) {
                    memberFetch.roles.add(annivRole);
                    console.log('[' + 'INFO'.yellow + '] Le rôle '.brightWhite + annivRole.name.yellow + " a été donné à " + memberFetch.user.username.brightBlue);
                    client.channels.cache.get(config.get("CANAL_GENERAL")).send("Fêtons l'anniversaire de <@" + memberFetch.id + "> ! :partying_face:").catch(console.error);
                }

            }
        }
    }
}

async function verifyMcChatWebhook() {
    let mcChatWebhookId = await botSettings.findOne({ where: { name: "mcChatWebhookId" } });
    let devMcChatWebhookId = await botSettings.findOne({ where: { name: "devMcChatWebhookId" } });

    if (mcChatWebhookId != null && devMcChatWebhookId != null) {
        console.log("[" + 'INFO'.yellow + "] Le Webhook du serveur MC est déjà configuré.");
        let mcChatWebhookToken = await botSettings.findOne({ where: { name: "mcChatWebhookToken" } });
        let devMcChatWebhookToken = await botSettings.findOne({ where: { name: "devMcChatWebhookToken" } });

        if (mcChatWebhookToken != null && devMcChatWebhookToken != null) {
            mcChatWebhook = new WebhookClient({ id: mcChatWebhookId.value, token: mcChatWebhookToken.value });
            devMcChatWebhook = new WebhookClient({ id: devMcChatWebhookId.value, token: devMcChatWebhookToken.value });
        } else {
            console.log("[" + 'ERREUR'.brightRed + "] Impossible de trouver le token du webhook dans la base de donnée.");
            createMcChatWebhook();
        }
    } else {
        createMcChatWebhook();
    }
}

async function createMcChatWebhook() {
    console.log("[" + 'INFO'.yellow + "] Création du Webhook du serveur MC.");
    client.channels.cache.get(config.get("CANAL_CHAT_MC")).createWebhook('Chat Serveur Minecraft', {
        avatar: 'https://sl-craft.fr/data/images/logo/short-color.png',
    })
        .then(webhook => {
            botSettings.create({
                name: "mcChatWebhookId",
                value: webhook.id
            });
            botSettings.create({
                name: "mcChatWebhookToken",
                value: webhook.token
            });
            mcChatWebhook = new WebhookClient({ id: webhook.id, token: webhook.token });
            console.log("[" + 'INFO'.yellow + "] Le Webhook du serveur MC a été configuré avec succès.");
        })
        .catch(console.error);

    // Dev
    client.channels.cache.get(config.get("CANAL_CHAT_MC_DEV")).createWebhook('Chat Serveur Minecraft Dev', {
        avatar: 'https://sl-craft.fr/data/images/logo/short-color.png',
    })
        .then(webhook => {
            botSettings.create({
                name: "devMcChatWebhookId",
                value: webhook.id
            });
            botSettings.create({
                name: "devMcChatWebhookToken",
                value: webhook.token
            });
            devMcChatWebhook = new WebhookClient({ id: webhook.id, token: webhook.token });
            console.log("[" + 'INFO'.yellow + "] Le Webhook du serveur MC Dev a été configuré avec succès.");
        })
        .catch(console.error);
}

function sendMessageFromMcChat(username, message, serverType) {
    if(username == "SL-Craft"){
        if(serverType == "dev"){
            devMcChatWebhook.send({
                content: message,
                username: username,
                avatarURL: 'https://sl-craft.fr/data/images/logo/favicon-color.png',
            });
        }else{
            mcChatWebhook.send({
                content: message,
                username: username,
                avatarURL: 'https://sl-craft.fr/data/images/logo/favicon-color.png',
            });
        }
    }else{
        // On va vérifier que le joueur ne fait pas de @everyone ou de @here
        message = message.replace("<@everyone>", "**everyone**");
        message = message.replace("<@here>", "**here**");
        message = message.replace("@everyone", "**everyone**");
        message = message.replace("@here", "**here**");

        // On va regarder si le joueur souhaite tagger quelqu'un avec un @
        var regex = /@(.*?\s)/g;
        var match = regex.exec(message);
        if (match){
            // console.log("ça a matché");
            var member = match[1].trim();
            // console.log(member+"flag");
            var memberFetch = client.users.cache.find(user => user.username == member).id;
            if (memberFetch){
                // console.log("Le membre existe");
                message = message.replace("@"+member, "<@" + memberFetch + ">");
            }
        }
        
        if(serverType == "dev"){
            devMcChatWebhook.send({
                content: message,
                username: username,
                avatarURL: 'https://live.mc.sl-projects.com/tiles/faces/32x32/' + username + '.png',
            });
        }else{
            mcChatWebhook.send({
                content: message,
                username: username,
                avatarURL: 'https://live.mc.sl-projects.com/tiles/faces/32x32/' + username + '.png',
            });
        }
        
    }
}


const job = schedule.scheduleJob('0 0 * * *', function () {
    console.log('[' + 'INFO'.yellow + '] Éxecution des tâches de fonds quotidiennes...'.brightWhite);
    checkAnniv();
});


// login to Discord with your app's token
client.login(config.get("DISCORD_BOT_TOKEN"));

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////

app.get('/ping', (req, res) => {
    res.send("Pong!")
})
app.get('/channels/:id', (req, res) => {
    var id = req.params.id;
    res.send(client.channels.cache.get(id));
})
app.get('/mc/chat/:detail', (req, res) => {
    var detail = JSON.parse(decodeURI(req.params.detail));
    sendMessageFromMcChat(detail.username, detail.message, req.headers['server-type']);
    res.send("Envoyé!")
})

app.listen(27001, () => {
    console.log('[' + 'INFO'.yellow + '] Écoute sur '.brightWhite + 'node.sl-projects.com:27001'.yellow);
});

////////////////////////////////////////////////////////////////