let userAccessLevels = { // Name | Text Colour | Background Colour | Border Colour
    "-3": ["Banned", "#fff", "#2e2e2e", "#727272"],
    "-2": ["Banned", "#fff", "#2e2e2e", "#727272"],
    "-1": ["Banned", "#fff", "#2e2e2e", "#727272"],
    "0": ["Member", "#fff", "#047205", "#00a003"],
    "1": ["Tester", "#fff", "#0c98a2", "#01c9d7"],
    "2": ["Moderator", "#000", "#00dc04", "#067708"],
    "3": ["Admin", "#fff", "#920606", "#c80404"],
}

function loginError(message, code = null) {
    let errorStr;
    if (code) {
        errorStr = `Status code ${code}: ${message}`;
    } else {
        errorStr = message;
    }

    document.getElementById("error-text").textContent = errorStr;

    document.getElementById("login-error").style.display = "block";
}

async function generateToken(username, password) {
    const credentials = btoa(`${username} ${password}`);

    let response;
    try {
        response = await fetch("https://account.spfn.net/api/v2/oauth2/generate_token", {
            method: "GET",
            headers: {
                "Authorization": `Basic ${credentials}`,
            }
        })
    } catch (err) {
        loginError(`Internal Server Error: ${err.message}`)
        throw new Error(err);
    }

    if (!response.ok) {
        if (response.status == 400) { // Invalid Login
            loginError("Invalid SFID or Password");
        } else {
            loginError(await response.text(), response.status);
        }

        throw new Error("Network Response was not okay when Generating Token");
    };
    
    const data = await response.json();

    sessionStorage.setItem("authToken", data["token"])

    const expiry = data["expiry"].slice(0, 19) + "Z"
    sessionStorage.setItem("authExpires", expiry)
    return data["token"];
}

async function getToken(username, password) {
    let token = sessionStorage.getItem("authToken");

    let expiryStr = sessionStorage.getItem("authExpires");
    if (expiryStr) { // Expiry exists so token should exist
        let expiry = new Date(expiryStr);
        if (expiry < new Date()) { // Expired token
            token = await generateToken(username, password);
        } else if (!token) { // Expiry Saved but No Token (shouldn't be possible but it'll be caught if it happens)
            token = await generateToken(username, password);
        }
    } else { // Token Never Saved in Session
        token = await generateToken(username, password);
    }

    return token
}

function updateUserDataDisplay(data) {
    document.getElementById("display-name").textContent = data["mii"]["name"];
    document.getElementById("sfid").textContent = `SFID: ${data["user_id"]}`;

    document.getElementById("email").innerHTML = `<strong>Email: </strong>${data["email"]["address"]}`;
    document.getElementById("dob").innerHTML = `<strong>Date of Birth: </strong>${data["birth_date"]}`;

    let createdAt = new Date(data["create_date"] + "Z");
    document.getElementById("created-at").innerHTML = `<strong>Created: </strong>${createdAt.toLocaleString()}`

    document.getElementById("tz").innerHTML = `<strong>Timezone: </strong>${data["tz_name"]}`;
    document.getElementById("region").innerHTML = `<strong>Country/Region: </strong>${data["country"]}`;

    document.getElementById("login").style.display = "none";
    document.getElementById("user-info").style.display = "flex";

    let miiLink = `https://mii.spfn.net/${data["pid"]}/main.png`
    document.getElementById("mii-img").src = miiLink;

    let level = userAccessLevels[data["account_level"]];
    document.getElementById("access-level").textContent = level[0];
    document.getElementById("access-level").style = `color: ${level[1]}; background-color: ${level[2]}; border-color: ${level[3]}`;
}

function logOut() {
    document.getElementById("login-error").style.display = "none";

    sessionStorage.clear();
    document.getElementById("user-info").style.display = "none";
    document.getElementById("login").style.display = "flex";
}

document.getElementById("login").addEventListener("submit", async function(event) {
    event.preventDefault();

    document.getElementById("login-error").style.display = "none";

    const username = await document.getElementById("username").value;
    const password = await document.getElementById("password").value;
    
    let token = await getToken(username, password);
    if (!token) return;

    document.getElementById("password").value = "";

    const response = await fetch("https://account.spfn.net/api/v2/users/@me/profile", {
        method: "GET",
        headers: {
            "Authorization": `Bearer ${token}`
        }
    })
    if (!response.ok) {
        loginError(await response.text(), response.status);
        throw new Error("Network Response was not okay when requesting Profile");
    }
    
    const data = await response.json();

    // Success - Display user data
    updateUserDataDisplay(data);
})



// Check if there is an active login
window.onload = async function() {
    let expiryStr = sessionStorage.getItem("authExpires");
    if (expiryStr) {
        let expiry = new Date(expiryStr);

        if (expiry > new Date()) { // Hasn't expired - Get user data
            let token = sessionStorage.getItem("authToken");

            const response = await fetch("https://account.spfn.net/api/v2/users/@me/profile", {
                method: "GET",
                headers: {
                    "Authorization": `Bearer ${token}`
                }
            })
            if (!response.ok) throw new Error("Network Response was not okay when requesting Profile")
        
            const data = await response.json();

            updateUserDataDisplay(data);
            document.getElementById("loading-screen").style.display = "none";
        
        } else { // Has expired - Prompt user to log back in
            document.getElementById("loading-screen").style.display = "none";
            document.getElementById("login").style.display = "block";

            loginError("Login expired - Please log in again")
        }
    } else { // User has never logged in for this session
        document.getElementById("loading-screen").style.display = "none";
        document.getElementById("login").style.display = "block";
    }
}

function showDeleteWarning() {
    document.getElementById("confirm-delete").style = ""
    document.getElementById("user-info").style = "display: none;"
}

function hideDeleteWarning() {
    document.getElementById("user-info").style = ""
    document.getElementById("confirm-delete").style = "display: none;"
}

async function deleteAccount() {
    let token = await getToken(username, password);

    const response = await fetch("https://account.spfn.net/api/v2/users/@me/delete", {
        method: "GET",
        headers: {
            "Authorization": `Bearer ${token}`
        }
    })

    if (!response.ok) {
        loginError(await response.text(), response.status);
        throw new Error("Network Response was not okay when requesting Account Deletion");
    }

    document.getElementById("confirm-delete").style = "display: none;"
    document.getElementById("delete-success").style = ""
}