// ==UserScript==
// @name         Ranked History
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  This script will generate a log of all locations. where you played ranked matches. To access the map, wait for the game page to load completely and press the "H" key on your keyboard.
// @author       HenriqueM
// @match        https://www.geoguessr.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @grant        none
// @license MIT
// ==/UserScript==
function loadjscssfile(filename, filetype){
    var fileref= undefined
    if (filetype=="js"){ //if filename is a external JavaScript file
        fileref=document.createElement('script')
        fileref.setAttribute("type","text/javascript")
        fileref.setAttribute("src", filename)
    }
    else if (filetype=="css"){ //if filename is an external CSS file
        fileref=document.createElement("link")
        fileref.setAttribute("rel", "stylesheet")
        fileref.setAttribute("type", "text/css")
        fileref.setAttribute("href", filename)
    }
    if (typeof fileref!="undefined") {
        document.getElementsByTagName("head")[0].appendChild(fileref)
    }
}
function loadMap() {
    // Criação da div do modal
    var modalDiv = document.createElement("div");
    modalDiv.id = "map-modal";
    modalDiv.style.position = "fixed";
    modalDiv.style.top = "0";
    modalDiv.style.right = "0";
    modalDiv.style.display = "flex";
    modalDiv.style.zIndex = "100";
    modalDiv.style.background = "white";
    modalDiv.style.justifyContent = "center";
    modalDiv.style.padding = "1rem";
    modalDiv.style.margin = "1rem";
    modalDiv.style.left = "50%";
    modalDiv.style.transform = "translate(-50%, 0)";
    // Criação da div do mapa dentro do modal
    var mapDiv = document.createElement("div");
    mapDiv.id = "world-map";
    mapDiv.style.width = "1000px";
    mapDiv.style.height = "600px";
    // Adicionando a div do mapa dentro da div do modal
    modalDiv.appendChild(mapDiv);
    // Adicionando a div do modal ao final do body do documento
    document.body.appendChild(modalDiv);
    $(function(){
        $('#world-map').vectorMap({
            map: 'world_mill',
            scaleColors: ['#C8EEFF', '#0071A4'],
            normalizeFunction: 'polynomial',
            hoverOpacity: 0.7,
            hoverColor: false,
            markerStyle: {
                initial: {
                    r: 4,
                    fill: '#F8E23B',
                    stroke: '#383f47'
                }
            },
            backgroundColor: '#383f47',
            markers: getAllCompetitiveLocations()
        
        });
    })
}
function getAllGameLocations() {
    let storageData = localStorage.getItem('gameLocations');
        if (storageData) {
            // A LocalStorage está definida, então analisar o conteúdo como JSON
            storageData = JSON.parse(storageData);
    
            // Verificar se o conteúdo é um array
            if (!Array.isArray(storageData)) {
                return []
            } else {
                const arrayDeArrays = storageData.map(game => game.rounds)
                const arrayAchatado = arrayDeArrays.reduce(function(acumulador, valorAtual) {
                    // Concatenar cada array no acumulador
                    return acumulador.concat(valorAtual);
                }, []);
                const formatado = arrayAchatado.map(l => {
                    return {
                        latLng: [l.lat, l.lng], 
                        name: ''
                    }
                })
                return formatado;
            }
        } else {
            return []
        }
}
function getAllCompetitiveLocations() {
    let storageData = localStorage.getItem('competitiveLocations');
        if (storageData) {
            // A LocalStorage está definida, então analisar o conteúdo como JSON
            storageData = JSON.parse(storageData);
    
            // Verificar se o conteúdo é um array
            if (!Array.isArray(storageData)) {
                return []
            } else {
                const arrayDeArrays = storageData.map(game => game.rounds)
                // Todo corrgiir o index abaixo
                const arrayDeArrays2 = storageData.map(game => game.teams[0].roundResults)
                const arrayAchatado = arrayDeArrays.reduce(function(acumulador, valorAtual) {
                    // Concatenar cada array no acumulador
                    return acumulador.concat(valorAtual);
                }, []);
                const arrayAchatado2 = arrayDeArrays2.reduce(function(acumulador, valorAtual) {
                    // Concatenar cada array no acumulador
                    return acumulador.concat(valorAtual);
                }, []);
                const formatado = arrayAchatado.map((l, i) => {
                    return {
                        latLng: [l.panorama.lat, l.panorama.lng], 
                        name: '',
                        color: '#5000ff',
                        style: {
                            fill: calcularCor(arrayAchatado2[i].score),
                            stroke: calcularCor(arrayAchatado2[i].score),
                        }
                    }
                })
                return formatado;
            }
        } else {
            return []
        }
}
function getGameMode() {
    if(location.pathname.includes("/battle-royale/") ) {
        return 'battle-royale'
    }
    if(location.pathname.includes("/duels/") ) {
        return 'duels'
    }
    return null
}
function calcularCor(valor) {
    // Normalizar o valor para um intervalo entre 0 e 1
    const normalizedValue = valor / 5000;
    // Calcular os componentes RGB da cor
    const red = Math.round(255 * (1 - normalizedValue));
    const green = Math.round(255 * normalizedValue);
    const blue = 0; // Sem azul para esta transição
    // Formatar a cor no formato RGB
    const cor = `rgb(${red}, ${green}, ${blue})`;
    return cor;
}
(function() {
    'use strict';
    async function getLocationObjectGame() {
        const tag = window.location.href.substring(window.location.href.lastIndexOf('/') + 1)
        const gameMode = getGameMode()
        console.log(getGameMode(), 'a');
        let game_endpoint = "https://www.geoguessr.com/api/v3/games/" + tag;
        if(gameMode) {
            game_endpoint = `https://game-server.geoguessr.com/api/${gameMode}/${tag}`
        }
        const api_url = game_endpoint
        const res = await fetch(api_url, {
            method: 'GET',
            credentials: 'include'
        });
        return await res.json();
    }
    async function saveGameLocations() {
        const chave = getGameMode() ? 'competitiveLocations' : 'gameLocations'
        const chavePrimaria = getGameMode() ? 'gameId' : 'token'
        // Obter o objeto de localização do jogo
        const gameinfo = await getLocationObjectGame();
    
        // Verificar se a LocalStorage está definida e se é um array
        let storageData = localStorage.getItem(chave);
        if (storageData) {
            // A LocalStorage está definida, então analisar o conteúdo como JSON
            storageData = JSON.parse(storageData);
    
            // Verificar se o conteúdo é um array
            if (!Array.isArray(storageData)) {
                // Se não for um array, definir como um array vazio
                storageData = [];
            } else {
                // Verificar se já existe um objeto com o mesmo token na LocalStorage
                const existingIndex = storageData.findIndex(item => item[chavePrimaria] === gameinfo[chavePrimaria]);
                if (existingIndex !== -1) {
                    // Se um objeto com o mesmo token foi encontrado, substituí-lo pelo novo objeto
                    storageData[existingIndex] = gameinfo;
                } else {
                    // Se não houver um objeto com o mesmo token, adicionar o novo objeto ao array
                    storageData.push(gameinfo);
                }
            }
        } else {
            // Se a LocalStorage não estiver definida, definir como um array contendo apenas o novo objeto
            storageData = [gameinfo];
        }
    
        // Salvar o array atualizado de volta na LocalStorage
        localStorage.setItem(chave, JSON.stringify(storageData));
    }
    
    function checkGameMode() {
        return location.pathname.includes("/game/") 
            || location.pathname.includes("/challenge/") 
            || location.pathname.includes("/battle-royale/") 
            || location.pathname.includes("/duels/");
    };
    
    function doCheck() {
        if (!document.querySelector('div[class*="result-layout_root__"]') && !document.querySelector('div[class*="game-finished-ranked_"]')) {
            sessionStorage.setItem("Checked", 0);
        } else if ((sessionStorage.getItem("Checked") || 0) == 0) {
            saveGameLocations();
            sessionStorage.setItem("Checked", 1);
        }
    };
    let lastDoCheckCall = 0;
    new MutationObserver(async (mutations) => {
        if (!checkGameMode() || lastDoCheckCall >= (Date.now() - 50)) return;
        lastDoCheckCall = Date.now();
        doCheck()
    }).observe(document.body, {
        subtree: true,
        childList: true
    });
    // ---------------
    
    document.addEventListener("keypress", function handleKeyPress(event) {
        // Verificar se a tecla pressionada é "h"
        if (event.key === "h") {
            loadMap()
        }
        if (event.key === "ç") {
            alert('salvo');
            saveGameLocations();
        }
    });
    loadjscssfile("https://code.jquery.com/jquery-3.7.1.min.js", "js") 
    loadjscssfile("https://cdnjs.cloudflare.com/ajax/libs/jvectormap/2.0.5/jquery-jvectormap.css", "css") 
    loadjscssfile("https://jvectormap.com/js/jquery-jvectormap-2.0.5.min.js", "js") 
    loadjscssfile("https://jvectormap.com/js/jquery-jvectormap-world-mill.js", "js")
})();