var express = require("express");
var cookieParser = require("cookie-parser");
var path = require("path");
var errorHandler = require("errorhandler");
var app = express();


app.use(cookieParser());
app.use((req, res, next) => {
    res.setHeader("Access-Control-Allow-Origin", "*");
    return next();
});
app.use(express.static(path.join(process.cwd(), "StaticPages")));
app.use(errorHandler({ dumpExceptions: true, showStack: true }));

var uuid = require("uuid/v4");
var mysql = require("mysql");
var fs = require("fs");
var cause;

var con = mysql.createConnection({
    host: "localhost",
    user: "minis",
    password: "lOkw83^2",
    database: "minis"
});

con.connect(err => {
    if (err) {
        console.log("Cant connect to MySQL database");
        console.log(err);
        cause = err;
    }
    console.log("Connected to database!");
});


app.get('/', (req, res) => {
    console.log(con);
    res.send("Welcome to the miniplan api!: " + cause);
});

app.get('/login', (req, res) => {
    var id = req.query.id;
    var password = req.query.password;

    if(id == undefined || password == undefined){
        res.send({success: false, error: "Missing parameters"});
        return;
    }

    id = id.toLowerCase();

    con.query("SELECT PASSWORT, USERNAME FROM ministranten WHERE (USERNAME='" + id + "' OR EMAIL='" + id + "')", (err, result) => {
        if (err) throw err;
        if(password == result[0]["PASSWORT"]){
            var usertoken = uuid();
            res.cookie("loginToken", usertoken);
            res.cookie("user", result[0]["USERNAME"]);
            con.query("UPDATE `ministranten` SET `USER_TOKEN` = '" + usertoken + "' WHERE `ministranten`.`USERNAME` = '" + result[0]["USERNAME"] + "';");
            res.send({success: true, token: usertoken});
        }else{
            res.send({success: false});
        }
    });
});

app.get("/logout", (req, res) => {
    var token = req.cookies.loginToken;
    var user = req.cookies.user;

    tokenIsValid(user, token).then(valid => {
        if(valid){
            con.query("UPDATE `ministranten` SET `USER_TOKEN` = '' WHERE `ministranten`.`USERNAME` = '" + user + "';");
            res.cookie("loginToken", "");
            res.cookie("user", "");
            res.send({success: true});
        }else{
            res.send({success: false});
        }
    });


});

app.get("/loggedIn", (req, res) => {
    var token = req.cookies.loginToken;
    var user = req.cookies.user;

    tokenIsValid(user, token).then(valid => {
        if(valid){
            res.send({success: true, loggedIn: true, user: user});
        }else{
            res.send({success: true, loggedIn: false, user: user});
        }
    })

});

/**
 * 
 * 
 *                              WIP
 * 
 * 
 * 
 */

app.get("/:user/update", (req, res) => {
    var token = req.cookies.loginToken;
    var user = req.params.user;
    var changes = JSON.parse(req.query.changes);


    tokenIsValid(req.cookies.user, token).then(valid => {
        if(valid){
            if(req.cookies.user != "admin" && req.cookies.user != user){
                res.send({success: false, error: "Unauthorized"});
                return;
            }
            
            console.log("Changing for " + user + " as " + req.cookies.user + " following states: ");
            console.log(changes);
            for(var i = 0; i < Object.keys(changes).length; i++){
                var gdID = Object.keys(changes)[i];
                var anwesenheit = changes[Object.keys(changes)[i]];
                con.query("INSERT INTO `anwesenheit` (USERNAME, gottesdienst_ID, ANWESENHEIT) VALUES('" + user + "', " + gdID + ", " + anwesenheit + ") ON DUPLICATE KEY UPDATE USERNAME='" + user + "', gottesdienst_ID=" + gdID + ", ANWESENHEIT=" + anwesenheit + "")
            }
        
            res.send({success: true});
        }else{
            console.log("Unauthorized not valid");
            res.send({success: false, error: "Unauthorized"});
        }
    });

});


app.get("/gottesdienste", (req, res) => {
    var groupid = req.params.groupid;
    con.query("SELECT ID from gruppe ORDER BY ID DESC LIMIT 1", (err, result) => {
        if (err) throw err;
        con.query("SELECT * from gottesdienst WHERE gruppe_ID='" + result[0]["ID"] + "' ORDER BY `gottesdienst`.`DATUM` ASC LIMIT 0 , 30 ", (err, result) => {
            if (err) throw err;
            res.send(JSON.stringify(result));
        });
    });
});

app.get("/gottesdienste/:groupid", (req, res) => {
    var groupid = req.params.groupid;
    con.query("SELECT * from gottesdienst WHERE gruppe_ID='" + groupid + "' ORDER BY  `gottesdienst`.`DATUM` ASC LIMIT 0 , 30", (err, result) => {
        if (err) throw err;
        res.send(JSON.stringify(result));
    });
});

app.get("/groups", (req, res) => {
    con.query("SELECT * from gruppe ORDER BY  `gruppe`.`ID` DESC  LIMIT 0, 5", (err, result) => {
        if (err) throw err;
        res.send(JSON.stringify(result));
    });
});

app.get("/ministranten", (req, res) =>{
    tokenIsValid(req.cookies.user, req.cookies.loginToken).then(valid => {
        con.query("SELECT `ministranten`.`USERNAME`, `ministranten`.`VORNAME`, `ministranten`.`NACHNAME`, `anwesenheit`.`ANWESENHEIT`, `anwesenheit`.`gottesdienst_ID` FROM `ministranten` LEFT JOIN `anwesenheit` ON `anwesenheit`.`USERNAME` = `ministranten`.`USERNAME` ORDER BY `ministranten`.`NACHNAME`, `ministranten`.`VORNAME`, `anwesenheit`.`gottesdienst_ID` DESC LIMIT 30", (err, results) => {
            if (err) throw err;
            var minis = [];
            
            var curMini;
            for(var i = 0; i < results.length; i++){
                
                var result = results[i];
                if(result["USERNAME"] == "admin"){
                    continue;
                }
                if(!curMini || curMini.username != result["USERNAME"]){
                    if(curMini != undefined || curMini != null){
                        minis.push(curMini);
                    }
                    curMini = {
                        firstname: result["VORNAME"],
                        lastname: valid ? result["NACHNAME"] : result["NACHNAME"].substring(0, 1) + ".",
                        username: result["USERNAME"],
                        registered: {}
                    }
                }
                curMini.registered[result["gottesdienst_ID"]] =  result["ANWESENHEIT"];
            }
            minis.push(curMini);
        
            res.send(JSON.stringify(minis));
            

        });
    })
        
});

var attachToMini = function(mini, pos, then){
    mini.registered = [];
    con.query("SELECT * FROM `" + mini.Name.toLowerCase() + "` ORDER BY  `" + mini.Name.toLowerCase() + "`.`GottesdienstIDs` DESC LIMIT 0 , 30", (err, data) => {
        if(data == null){
            then(mini, pos);
        }
        for(var j = 0; j < data.length; j++){
            
            mini.registered[j] = {
                id: data[j]["GottesdienstIDs"],
                value: data[j]["Anwesend"]
            };
        }
        then(mini, pos);
    });
}


app.listen(process.env.PORT);
console.log("Starting api-server on " + process.env.PORT);



function tokenIsValid(username, token){
    return new Promise((resolve, reject) => {
        con.query("SELECT USER_TOKEN FROM ministranten WHERE USERNAME='" + username + "'", (err, result) => {
            if (err) {
                reject(err);
                return;
            };

            if(result.length == 0){
                resolve(false);
                return;
            }
    
            if(result[0]["USER_TOKEN"] != "" && result[0]["USER_TOKEN"] == token){
                resolve(true);
            }else{
                resolve(false);
            }
        });
    })
}



function removeFromArrayByValue(value, array) {
    var index = array.indexOf(value);
    if(index > -1){
        array.splice(index, 1);
    }
}

function removeFromArray(index, array) {
    var index = array.indexOf(value);
    if(index > -1){
        array.splice(index, 1);
    }
}