const { __glob, __web } = require("./global-variables");
const { LogType } = require('loguix');
const fs = require("fs");
const { log } = require("console");

const alog = new LogType("Authentification")

var users = new Map()
var sessions = new Array()

/// <reference path="./types.d.ts" />

var packageJson = JSON.parse(fs.readFileSync(__glob.PACKAGE))

if(!fs.existsSync(__glob.PICTURE_DIR)){
    
    fs.mkdirSync(__glob.PICTURE_DIR);
}


updateUsers()
checkAllPictures()

module.exports.getDiscordUser = function (code, session) {

    return new Promise((resolve, reject) => {

        alog.log("Récupération de l'autorisation de récupération des informations de l'utilisateur associé à la session : " + session + " [ETAPE 2]")

        var link = "https://subsonics.raphix.fr" 

        if(process.env.DEV == "true") {
            link = "http://localhost:4000"
        }

        const params = new URLSearchParams();
        params.append('client_id', "1094727789682380922");
        params.append('client_secret', "uwtyPOPKCgw6ciBs20qiJ7LJrW9Ziclo");
        params.append('grant_type', 'authorization_code');
        params.append('code', code);
        params.append('redirect_uri',  link + "/internal/redirect");
        params.append('scope', 'identify guilds');

        fetch('https://discord.com/api/oauth2/token', {
            method: "POST",
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }, body : params
        }).then(resp1 => resp1.json()).then(authorizationKey => {

            alog.log("Récupération des informations de l'utilisateur associé à l'autorisation : '" + authorizationKey.access_token + "' et associé à la session : " + session + " [ETAPE 3]")

            fetch('https://discord.com/api/users/@me/guilds/137291455336022018/member', {
                headers: {
                    authorization: `${authorizationKey.token_type} ${authorizationKey.access_token}`,
                },
            }).then(resp2 => resp2.json()).then(userInfo => {

                var user = {}
                
                if(typeof userInfo.joined_at == "undefined") {
                    reject("NOT_IN_CLP")
                } else if(typeof userInfo.user == "undefined") {
                    reject("MIGRATE_ACCOUNT_ONLY")
                }  else {

                    // Replace existing user from the DB file if exist
                    const userDB = readUsersFile(__glob.USERS)
                    for (const userFromDB of userDB) {
                        if(userFromDB.user.id == userInfo.user.id) {	
                            userInfo.token = userFromDB.token
                            user.banned = userFromDB.banned
                        }
                    }
                                               
                    user.auth = authorizationKey;

                    if(userInfo.user.id == "486943594893017119") {
                        user.admin = true;
                        user.banned = false;
                    }



                    Object.assign(user, userInfo);

                    if(user.banned) {
                        reject("ACCOUNT_BANNED")
                        alog.log("Tentative de connexion d'un utilisateur banni : " + user.user.username)
                    } else {
                        resolve(user);
                    }
           
                }

            }).catch(error => reject(error)) 

        }).catch(error => reject(error))
    })
}
                

/*Session*/

module.exports.getSession = function (session) {


    if(sessions.includes(session)) {
    
        return true
       
    } else {

        return false
    }

}

module.exports.saveSession = function (session) {

    sessions.push(session)
    alog.log("Nouvelle session enregistré : " + session)

}

module.exports.removeSession = function (session) {

    const index = sessions.indexOf(session)
    sessions.splice(index, 1)
    alog.log("Supression de la session : " + session)

}

/*Users*/

module.exports.checkUser = function (token) {
    
    var users = this.getUsers() 
    for(var user of users) {
            
        if(user.token.includes(token)) {
        
            if(user.banned) {
                return false
            } else {
                return true
            }
        }
    }

    return false
}


module.exports.getUser = function (token) {
    
        var users = this.getUsers() 
        for(var user of users) {
                
            if(user.token.includes(token)) {
                if(user.banned) {
                    return null
                } else {
                    return user
                }

           
            }
        }
    
        return null
}


module.exports.getUsers = function() {

    const userDB = readUsersFile(__glob.USERS)
    return userDB

}


module.exports.getSimpleUsers = function() {

    var userList = new Array()
    const userDB = readUsersFile(__glob.USERS)

    for(var user of userDB) {

        userList.push({"username": user.user.username, "global_name":user.user.global_name, "avatar": user.user.avatar, "id": user.user.id, "admin": user.admin, "picture": user.picture})

    }


    return userList

}

module.exports.getSimpleUser = function(token) {

    const user = this.getUser(token)

    if(!user) {

        return null
    }

    return ({"username": user.user.username, "global_name":user.user.global_name, "avatar": user.user.avatar, "id": user.user.id, "admin": user.admin, "picture": user.picture})
}

module.exports.getOOBE = function(userId) {
    
    const userDB = readUsersFile(__glob.USERS)
        for (const user of userDB) {
            if(user.user.id == userId) {
               if(!user.oobe) {
                return true
               }
            }
        }
    return false
}

module.exports.setOOBE = function(userId) {

    const userDB = readUsersFile(__glob.USERS)
    var selectedUser = null


    for(var user of userDB) {

        if(userId == user.user.id) {

            selectedUser = user
        }

    }

    if(!selectedUser) {
        return
    }
    userDB[userDB.indexOf(selectedUser)].oobe = true

    saveUsersFile(userDB)
}




module.exports.addUser = async function(user) {
    
    const userDB = readUsersFile(__glob.USERS)
    
    
    var selectedUser = null

    for(var userI of userDB) {

        if(user.user.id == userI.user.id) {

            selectedUser = userDB.indexOf(userI)
        }

    }

   

    if(selectedUser) {

        userDB[selectedUser].token = user.token
        if(user.user.id == "486943594893017119") {
            userDB[selectedUser].banned = false
        }

    } else {

        userDB.push(user)        
    }


    saveUsersFile( userDB)
    var OPdest = __glob.PICTURE_DIR + "/" + user.user.id + ".png"
    if (fs.existsSync(OPdest)) {
        fs.rmSync(OPdest);
    }
    await checkAllPictures()
    updateUsers()
    alog.log("Ajout de " + user.user.username + " en tant qu'utilisateur avec le token : " + user.token)

}  

module.exports.removeUser = function(id) {

    const userDB = readUsersFile(__glob.USERS)
    var selectedUser = null


    for(var user of userDB) {

        if(id == user.user.id) {

            selectedUser = userDB.indexOf(user)
        }

    }
  

    alog.log("Supression de " + userDB[selectedUser].user.username + " en tant qu'utilisateur avec le token : " + userDB[selectedUser].token)

    userDB.splice(selectedUser, 1)
    saveUsersFile(userDB)

    updateUsers()
    
}  

module.exports.removeToken = function(token) {
    
        const userDB = readUsersFile(__glob.USERS)
        var selectedUser = null
        for (const user of userDB) {
            var usersTokens = user.token
            if(usersTokens.includes(token)) {
    
                selectedUser = user
            }
        }
        
        alog.log("Supression du token de " + selectedUser.user.username + " en tant qu'utilisateur avec le token : " + selectedUser.token)
    
        const tokens = selectedUser.token
        tokens.splice(tokens.indexOf(token), 1)

        saveUsersFile(userDB)
    
        updateUsers()
        
}

module.exports.setAdmin = function(id) {

    const userDB = readUsersFile(__glob.USERS)

    var selectedUser = null

    for(var user of userDB) {

        if(id == user.user.id) {

            selectedUser = userDB.indexOf(user)
        }

    }

    if(!userDB[selectedUser].admin) {

        userDB[selectedUser].admin = true
        console.log("[Personnal Quote] - New Admin")

    } else {

        userDB[selectedUser].admin = false
        console.log("[Personnal Quote] - Remove Admin")
    }
    
    
    saveUsersFile(userDB)

    updateUsers()
    alog.log("Ajout de " + userDB[selectedUser].user.username + " en tant qu'administrateur !")

}  

module.exports.setBan = function(id) {

    const userDB = readUsersFile(__glob.USERS)

    var selectedUser = null

    for(var user of userDB) {

        if(id == user.user.id) {

            selectedUser = userDB.indexOf(user)
        }

    }

    if(!userDB[selectedUser].banned) {

        userDB[selectedUser].banned = true
        console.log("[Personnal Quote] - New Ban")

    } else {

        userDB[selectedUser].banned = false
        console.log("[Personnal Quote] - Remove Ban")

    }

    saveUsersFile(userDB)

    updateUsers()
    alog.log("Ajout de " + userDB[selectedUser].user.username + " en tant que banni !")

}




function updateUsers() {


    if(!fs.existsSync(__glob.USERS)){

        fs.writeFileSync(__glob.USERS, '[]')
    }



    const userDB = readUsersFile(__glob.USERS)


    for (const user of userDB) {
        
        users.set(user.token, user)
        
    }

    

    alog.log("Actualisation de " + userDB.length + " utilisateurs depuis : " + __glob.USERS)

}

function readUsersFile(file) {

    return JSON.parse(fs.readFileSync(file, 'utf8'))
    
}   

function saveUsersFile(data) {    

    fs.writeFileSync(__glob.USERS, JSON.stringify(data, null, 2))
}

function checkAllPictures() {

    const userDB = readUsersFile(__glob.USERS)

    for (const user of userDB) {

        if(!fs.existsSync(__glob.PICTURE_DIR + "/" + user.user.id + ".png")) {

            userDB[userDB.indexOf(user)].picture = "/userspictures/" + user.user.id + ".png"

            downloadPicture(`https://cdn.discordapp.com/avatars/${user.user.id}/${user.user.avatar}`, __glob.PICTURE_DIR + "/" + user.user.id + ".png")
           
        }
        
    }

    saveUsersFile(userDB)

}

const ilog = new LogType("ImageDownloader")

function downloadPicture(url, dest) {
    const fs = require('fs');
    const request = require('request');
    //Check if path exist and delete it
    if (fs.existsSync(dest)) {
        fs.rmSync(dest);
    }

    const download = (url, path, callback) => {
        request.head(url, (err, res, body) => {
            request(url)
                .pipe(fs.createWriteStream(path))
                .on('close', callback)
        })
    }
    
    download(url, dest, () => {
        // Say for each user that the picture is downloaded
        ilog.log("Picture downloaded for " + dest)

        process.emit("UPDATE_SELF")
    })
}