/**
 * Genera un UUID Version 4
 * @returns 
 */
export const v4 = () => {
    var d = new Date().getTime();
    if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
        d += performance.now(); //use high-precision timer if available
    }
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
}


/**
 * Genera un UUID Coord
 * @param {number} x 
 * @param {number} y 
 * @param {number} z 
 * @param {string} dimension 
 * @returns 
 */
export const v4Coords = (x, y, z, dimension) => {
    var d = new Date().getTime();
    if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
        d += performance.now(); //use high-precision timer if available
    }
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    }) + `(${x},${y},${z})(${dimension})`;
}


/**
 * Recupera las coordenadas de un UUID Coord
 * @param {string} uuidString 
 * @returns 
 */
export const getCoordinatesFromUUID = (uuidString) => {
    const matches = uuidString.match(/\((-?\d+),(-?\d+),(-?\d+)\)/);
    if (matches === null) {
        return null;
    }
    const [, x, y, z] = matches;
    return { x: parseInt(x), y: parseInt(y), z: parseInt(z) };
}

/**
 * Busca un UUID Coord por un elemento de coordenadas
 * @param {{x: number, y: number, z: number}} coordinates 
 * @param {Array<string>} uuids 
 * @returns 
 */
export const findUUIDByCoordinates = (coordinates, uuids) => {
    const { x, y, z } = coordinates;
    for (const uuidString of uuids) {
        const uuidCoordinates = getCoordinatesFromUUID(uuidString);
        if (uuidCoordinates === null) {
            continue;
        }
        if (uuidCoordinates.x === x && uuidCoordinates.y === y && uuidCoordinates.z === z) {
            return uuidString;
        }
    }
    return null;
}

/**
 * Verifica la existencia de un UUID Coord
 * @param {{x: number, y: number, z: number}} coordinates 
 * @param {Array<string>} uuids 
 * @returns 
 */
export const isUUIDByCoordinates = (coordinates, uuids) => {
    const { x, y, z } = coordinates;
    for (const uuidString of uuids) {
        const uuidCoordinates = getCoordinatesFromUUID(uuidString);
        if (uuidCoordinates === null) {
            continue;
        }
        return uuidCoordinates.x === x && uuidCoordinates.y === y && uuidCoordinates.z === z;
    }
    return false;
}

/**
 * Filtra los UUID Coords por dimesion
 * @param {Array<string>} playerTags 
 * @param {string} dimension 
 * @returns 
 */
export const filterCoordinateTags = (playerTags, dimension) => {
    return playerTags.filter(tag => {
        const coord = getCoordinatesFromUUID(tag);
        if(coord !== null) {
            return tag.includes(dimension);
        } else {
            return false;
        }
    });
}