import { type Vector3 } from '@babylonjs/core';

/**
 * A 3D spatial map that uses Vector3 coordinates as keys.
 * ONLY supports integer coordinates.
 * @typeParam T - The type of values stored in the map.
 */
export class IntVector3Map<T> {
    private _xMap = new Map<number, Map<number, Map<number, T>>>();

    /**
     * Creates a new IntVector3Map instance.
     * @returns {@link IntVector3Map} instance.
     */
    static create<T>(): IntVector3Map<T> {
        return new IntVector3Map<T>();
    }

    /**
     * Gets an existing value for the given coordinates.
     * @param intVector - The 3D coordinates to use as the key.
     * @returns The value if found, otherwise undefined.
     */
    get(intVector: Vector3): T | undefined {
        const { x, y, z } = intVector;
        return this._xMap.get(x)?.get(y)?.get(z);
    }

    /**
     * Sets a value for the given coordinates.
     * @param intVector The 3D coordinates to use as the key.
     * @param value The value to set.
     */
    set(intVector: Vector3, value: T): void {
        const { x, y, z } = intVector;

        let yMap = this._xMap.get(x);
        if (!yMap) {
            yMap = new Map<number, Map<number, T>>();
            this._xMap.set(x, yMap);
        }
        let zMap = yMap.get(y);
        if (!zMap) {
            zMap = new Map<number, T>();
            yMap.set(y, zMap);
        }
        zMap.set(z, value);
    }
}
