const Net = require('net');
const port = 6033;
const { Webhook } = require('discord-webhook-node');
const hook = new Webhook("https://discord.com/api/webhooks/1157030453807698040/K80q5yE4qvKeAi7W4arGyP5YH82dTiGDALw2ESU7uzQ3b_Nv5ylgKno80sLsOTVnVQV5");
const server = new Net.Server();
const botToken = 'MTE1NzAzNDUyMzAyMDc1OTE3MA.GQH1hm.H4vZIz1IpbX31xtTObuIUZa1sN9m5VrM_f0iU0'
server.listen(port, function() {
    console.log(`Server listening for connection requests on socket localhost:${port}`);
});
messageQueue = []
const CryptoJS = require("crypto-js");
const Discord = require("discord.js");
const { Client, GatewayIntentBits, SlashCommandBuilder  } = require('discord.js');
const { MessageMentions: { USERS_PATTERN } } = require('discord.js');
const { v4: uuidv4 } = require('uuid');
var hasleader = false
var ignoreBuffer = []
const client = new Discord.Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent
  ]
})
const commands = {}
client.on("messageCreate", function(message) {
    nickname = false
    if (message.author.bot) return;
    if (message.channelId != "1128902878166269962") return;
    guild = client.guilds.cache.get(message.guildId)
    guild.members.cache.forEach((member) => {
        if (member.user.id == message.author.id) {
            nickname = member.nickname
        }
    })
    if (nickname == false || nickname === null) {
        nickname = message.author.globalName
    }
    ignoreBuffer.push("[" + nickname + "] " + message.content.replace(/[\n\r]/g, ''))
    messageQueue.push("[" + nickname + "] " + message.content.replace(/[\n\r]/g, ''))
    if(ignoreBuffer.length > 1000) {
        ignoreBuffer.shift()
    }
  });
client.login(botToken);
messageBuffer = []
sentMessages = []

var checkDuplicate = (message_hash, time) => {
    for (let msg of sentMessages) {
        if (msg.hash == message_hash) {
            let differential = Math.abs(time - msg.time)
            if (differential <= 1) {
                return true
            }
        }
    }
    return false
}

var processBuffer = () => {
    if(messageBuffer.length) {
        msg = messageBuffer.shift()
        duplicate = true
        rawInventoryString = String(msg.metaData.server) + String(msg.payload.name) + String(msg.payload.message.replace(/[\n\r]/g, ''));
        msgTime = String(msg.metaData.time) 
        hashedIS = CryptoJS.MD5(rawInventoryString).toString()
        
        if(!checkDuplicate(hashedIS, msgTime) && !ignoreBuffer.includes(msg.payload.message.replace(/[\n\r]/g, ''))) {
            let msgStore = {
                "hash": hashedIS,
                "time": msgTime
            }
            sentMessages.push(msgStore)
            if (sentMessages.length > 100) {
                sentMessages.shift()
            } 
            hook.setUsername(msg.payload.name); 
            hook.setAvatar("https://ui-avatars.com/api/?background=random&name=" + msg.payload.name)
            hook.send(msg.payload.message.replace(/[\n\r]/g, ''));
            if(msg.payload.message.toLowerCase().includes("discord info") || msg.payload.message.toLowerCase().includes("discord invite") || msg.payload.message.toLowerCase().includes("invite to discord")) {
                msg.metaData.server = 255
                msg.payload.message = 'https://discord.gg/9ydGN8AHUu'
                messageQueue.push(msg.payload.message)
            }
        } else {
            console.log("Duplicate Detected.")
        }
    }
    setTimeout(processBuffer, 250)
}

var processSocketResponse = (socket) => {
    if(messageQueue.length) {
        socket.write(messageQueue.shift() + '\n')
    } else {
        socket.write('PONG\n');
    }
    socket.lastPingTime = new Date();
}

var removeSocketAsLeader = (socket) => {
    if (socket.isLeader) { hasleader = false }
}
setTimeout(processBuffer, 5000)
ffxiClient = {
    
}
server.on('connection', function(socket) {
    socket.uid = uuidv4();
    console.log('A new connection has been established.');
    socket.write('CONNECTION_ACCEPTED\n');

    socket.on('data', function(chunk) {
        payload = JSON.parse(chunk.toString())
        if(payload['type'] == "MESSAGE") {
            messageBuffer.push(payload)
            socket.linkshell = payload.payload.linkshellname
            socket.write('RECEIVEDOK\n');
            console.log(payload);
        } else if (payload['type'] == "PING") {
            processSocketResponse(socket)
        } else if (payload['type'] == "OTHER") {
            socket.write('RECEIVEDOK\n');
        } else if (payload['type'] == "HANDSHAKE") {
            socket.write('WELCOME\n');
        }    
    });

    socket.on('end', function() {
        removeSocketAsLeader(socket)
        console.log('Closing connection with the client');
        
    });


    socket.on('error', function(err) {
        removeSocketAsLeader(socket)
        console.log(`Error: ${err}`);
    });
});
//