const { Console } = require('console');
const dgram = require('dgram');
const { currentGame, resetGame } = require("../utils/partyManager");
const { wsBroadcast } = require("../utils/websocketManager");


const server = dgram.createSocket({ type: 'udp4', reuseAddr: true });
const options = { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' };
let keys = [];

let events = [
    (key, message, remote, full, date) => {
        console.log(date.toLocaleDateString("en-FR", options) + ' - MESSAGE FROM: ' + remote.address + ':' + remote.port + ' - ' + full)

        if (!keys.includes(key)) {
            keys.push(key);
        }
        console.log(currentGame.context());
    }
]

server.on('listening', function () {
    const address = server.address();
    console.log('UDP Client listening on ' + address.address + ":" + address.port);
    console.log("multicast adress on " + process.env.UDP_ADDR);
});

server.on('message', function (message, remote, date = new Date) {
    const split = (message + "").split(process.env.UDP_SEP);
    if (split[0] == process.env.SERVER_NAME && split.length >= 3) {
        for (e of events) {
            e(split[1], split[2], remote, message, date);
        }
    }
});

function startUdp(port = process.env.PORT_UDP, host = process.env.HOST, address = process.env.UDP_ADDR) {
    server.bind({ port, exclusive: true }, function () {
        server.addMembership(address);
    });
    addMessageListener((key, message, remote, full, date) => {
        if (message == "CONNECT") {
            currentGame.addPlayer(key);
            sendMessageAll("SERVER_TEST");
        }
    });
    addMessageListener((key, message, remote, full, date) => {
        if (message == "HIT") {
            if (currentGame.startTime && !currentGame.finishTime) {
                currentGame.addEvent(key);
                wsBroadcast(JSON.stringify({
                    message: {
                        key: key,
                        action: "HIT"
                    },
                    context: currentGame.context()
                }))
            }
        }
    });
    addMessageListener((key, message, remote, full, date) => {
        if (message == "PONG") {
            currentGame.addPlayer(key);
        }
    });
}

function ping(id) {
    console.log(id);
    if(id) {
        sendMessageWithKey("PING", id);
    } else {
        sendMessageAll("PING");
    }
}

function addMessageListener(messageFunc) {
    events.push(messageFunc);
}

function addKeys(key) {
    keys.push(key);
}

function parseMessage(message) {
    return message + "";
}

function sendMessageWithKey(message, key) {
    const mes = key + process.env.UDP_SEP + process.env.SERVER_NAME + process.env.UDP_SEP + message;
    sendMessage(mes);
}

function sendMessageAll(message) {
    for (key of keys) {
        sendMessageWithKey(message, key);
    }
}

function sendMessage(message, date = new Date()) {
    console.log(date.toLocaleDateString("en-FR", options) + " - MESSAGE SEND : " + message);
    server.send(message, 0, message.length, process.env.PORT_UDP, process.env.UDP_ADDR);
}

module.exports = { startUdp, addMessageListener, parseMessage, sendMessage, addKeys, ping, keys, sendMessageWithKey, sendMessageAll }

