const { ipcRenderer } = require('electron')
const path = require('path');

const express = require('express')
const app = express()
const server = require('http').createServer(app)
const io = require('socket.io')(server)

const base64 = require('base-64');
const utf8 = require('utf8');

let publicPath = path.resolve(__dirname, './public');
let serverRunning = false


app.use(express.static(publicPath))
app.use(express.json())


io.on('connection', function (client) {
    console.log('Client connected.')

    //#region Client to Server communication
    client.on('U2S_getLanguage', function (data) {
        ipcRenderer.send('ipcS2M_getGameDict')
    })

    client.on('U2S_loginStudent', function (data) {
        let decoded = utf8.decode(base64.decode(data));
        console.log(decoded)
        ipcRenderer.send('ipcS2M_loginStudent', { username: decoded, socketid: client.id })
    })

    client.on('U2S_getAssignedNodes', function (data) {
        ipcRenderer.send('ipcS2M_getAssignedNodes', { socketid: client.id })
    })

    client.on('U2S_voteForNode', function (data) {
        ipcRenderer.send('ipcS2M_voteForNode', JSON.parse(data))
    })

    client.on('U2S_submitQuestion', function (data) {
        let decoded = utf8.decode(base64.decode(data));
        ipcRenderer.send('ipcS2M_submitQuestion', JSON.parse(decoded))
    })

    client.on('U2S_submitSticker', function (data) {
        ipcRenderer.send('ipcS2M_submitSticker', data)
    })

    client.on('U2S_submitScreenshot', function (data) {
        ipcRenderer.send('ipcS2M_submitScreenshot', data)
    })


    //#endregion

    //#region Server to Client communication
    ipcRenderer.on('ipcM2S_submitGameDict', (event, arg) => {
        let msg = JSON.stringify( arg )
        let encoded = base64.encode(utf8.encode( msg ))

        client.emit('S2U_languageSet', encoded);
    })

    ipcRenderer.on('ipcM2S_requestScreenshot', (event, arg) => {
        client.emit('S2U_requestScreenshot', arg);
    })

    ipcRenderer.on('ipcM2S_pushPlayerInfo', (event, arg) => {
        let msg = JSON.stringify( { playerlist: arg } )
        let encoded = base64.encode(utf8.encode( msg ))

        client.emit('S2U_playerInfoUpdated', encoded);
    })

    ipcRenderer.on('ipcM2S_gameStateChanged', (event, arg) => {
        client.emit('S2U_gameStateChanged', arg);
    })

    ipcRenderer.on('ipcM2S_timerChanged', (event, arg) => {
        client.emit('S2U_timerChanged', arg);
    })

    ipcRenderer.on('ipcM2S_pushAssignedNodesToClients', (event, arg) => {
        console.log(arg)
        let msg = JSON.stringify({ randomSeed: arg.randomSeed, subtopics: arg.nodeData })
        let encoded = base64.encode(utf8.encode( msg ))

        client.emit('S2U_nodesAssigned', encoded);
    })

    ipcRenderer.on('ipcM2S_listAcceptedQuestions', (event, arg) => {
        console.log(arg)
        let msg = JSON.stringify({ acceptedQuestions: arg })
        let encoded = base64.encode(utf8.encode( msg ))

        client.emit('S2U_listAcceptedQuestions', encoded);
    })


    ipcRenderer.on('ipcM2S_pushModifiedNodes', (event, arg) => {
        console.log(arg)
        client.emit('S2U_modifiedNodes', JSON.stringify({
            revealed: arg.revealed,
            selectable: arg.selectable,
            visited: arg.visited,
            forced: arg.forced
        }))
    })

    ipcRenderer.on('ipcM2S_moveVoteResult', (event, arg) => {
        console.log(arg)
        client.emit('S2U_moveVoteResult', arg);
    })

    ipcRenderer.on('ipcM2S_teamEvaluation', (event, arg) => {
        console.log(arg)
        client.emit('S2U_turnEvaluationResult', JSON.stringify({
            teamResult: [arg["1"], arg["2"], arg["3"]]
        }))
    })

    ipcRenderer.on('ipcM2S_endgameSubtopic', (event, arg) => {
        console.log(arg)

        let msg = JSON.stringify({
            subtopic: arg.subtopic,
            question: arg.question,
            correct: arg.correct,
            wrong: arg.wrong
        })
        let encoded = base64.encode(utf8.encode( msg ))

        client.emit('S2U_endgameSubtopic', encoded)
    })

    ipcRenderer.on('ipcM2S_endgameRoundResults', (event, arg) => {
        console.log(arg)

        let msg = JSON.stringify({
            team1Result: arg.results['1'],
            team2Result: arg.results['2'],
            team3Result: arg.results['3'],
            subtopic: arg.subtopic.subtopic,
            question: arg.subtopic.question,
            correct: arg.subtopic.correct,
        })
        let encoded = base64.encode(utf8.encode( msg ))

        client.emit('S2U_endgameRoundResults', encoded)
    })

    ipcRenderer.on('ipcM2S_playerScores', (event, arg) => {

        let msg = JSON.stringify({ playerScores: arg })
        let encoded = base64.encode(utf8.encode( msg ))

        client.emit('S2U_playerScores', encoded)
    })


    ipcRenderer.on('ipcM2S_stickerPlacement', (event, arg) => {
        let encoded = base64.encode(utf8.encode( arg ))
        client.emit('S2U_stickerPlacement', encoded)
    })

    ipcRenderer.on('ipcM2S_stopStickerPlacement', (event, arg) => {
        client.emit('S2U_stopStickerPlacement')
    })



    //#endregion

})

//#region Server reply to specific socket ID

ipcRenderer.on('ipcM2S_loginStudentReply', (event, arg) => {
    let replyData = arg['data']
    let socketid = arg['socketid']

    let msg = JSON.stringify( replyData )
    let encoded = base64.encode(utf8.encode( msg ))

    io.to(socketid).emit('S2U_loginResponse', encoded)
})

ipcRenderer.on('ipcM2S_pushAssignedNodesToSockedID', (event, arg) => {
    let replyData = arg['data']
    let socketid = arg['socketid']

    let msg = JSON.stringify({ randomSeed: replyData.randomSeed, subtopics: replyData.nodeData })
    let encoded = base64.encode(utf8.encode( msg ))

    io.to(socketid).emit('S2U_nodesAssigned', encoded)
})

//#endregion

ipcRenderer.on('ipcM2S_startServer', (event, arg) => {
    if (!serverRunning) {
        server.listen(arg)
        serverRunning = true
    }
}) 
