import { BC_TERRAIN_MANAGER, BC_TERRAIN_SETTINGS } from "../../GlobalVariables/GlobalVariables";
import { PointInt2D } from "../../Utils/Math.utils";
import { PathFinder } from "../../Utils/PathFinding.utils";
import { TerrainTile } from "../../WorldGenV2/Tiles/TerrainTile";
// import { getWorldChunkAt, worldCoordinatesToChunkLocalCoordinates } from "../../WorldGeneration/WorldGen";
// import { TerrainTile } from "../../WorldGeneration/WorldObjects/TerrainTile/TerrainTile";

export class NavigationGridTile
{
    position = new PointInt2D();
    movementCost = 0;
    isObstacle = false;
    /**
     * @type {TerrainTile}
     */
    optionalTerrainTileRef = null;

    /**
     * 
     * @param {PointInt2D} pos 
     * @param {Number} cost 
     * @param {Boolean} isObstacle 
     */
    constructor(pos, cost, isObstacle, ref = null)
    {
        this.position = pos;
        this.movementCost = cost;
        this.isObstacle = isObstacle;
        this.optionalTerrainTileRef = ref;
    }
}

/**
 * @param {NavigationGridTile} tile 
 */
function NavigationGridTileSettingsChangeFunctor(tile) {
    
}

export class NavigationGridChunk
{
    /**
     * @type {Map<String, NavigationGridTile>}
     */
    _gridTiles = new Map();

    /**
     * 
     * @param {NavigationGridTile} element 
     * @param {String} id 
     */
    addToChunk(element, id)
    {
        this._gridTiles.set(id, element);
    }

    getFromChunkById(id)
    {
        return this._gridTiles.get(id);
    }

    getFromChunk(xWorld, yWorld)
    {
        let key = Math.floor(xWorld / BC_TERRAIN_SETTINGS.totalSize) * BC_TERRAIN_SETTINGS.totalSize + "_" + Math.floor(yWorld / BC_TERRAIN_SETTINGS.totalSize) * BC_TERRAIN_SETTINGS.totalSize;
        return this._gridTiles.get(key);
    }

    /**
     * 
     * @param {String} id 
     * @param {NavigationGridTileSettingsChangeFunctor} func 
     */
    changeNavigationGridTileSettings(id, func)
    {
        let t = this._gridTiles.get(id);
        if(t)
        {
            func(t);
            return true;
        }
        return false;
    }
}


// export class NavigationGrid
// {   

//     /**
//      * 
//      * @param {Number} xWorld 
//      * @param {Number} yWorld 
//      */
//     static getNavigationGridTile(xWorld, yWorld)
//     {
//         let chunk = getWorldChunkAt(xWorld, yWorld);
//         if(chunk)
//         {
//             return chunk.navigationGridChunk.getFromChunk(xWorld, yWorld);
//         }
//         return undefined;
//     }
// }

/**
 * @param {Number} xWorld 
 * @param {Number} yWorld 
 * @returns 
 */
export function getNavigationGridTile(xWorld, yWorld)
{
    let chunk = BC_TERRAIN_MANAGER.getChunkAt(new PointInt2D(xWorld, yWorld));
    // console.log(chunk);
    if(chunk)
    {
        return chunk.navigationChunk.getFromChunk(xWorld, yWorld);
    }
    return undefined;
}

function NavigationGridPathFinderCallback(result) {
    
}

async function _findPathAsync(start, goal)
{
    let pf = new PathFinder();
    return pf.search(start, goal);
}
/**
 * @param {PointInt2D} start 
 * @param {PointInt2D} goal 
 */
export async function findPathOnNavigationGridIfExists(start, goal) {
    let r0 = await _findPathAsync(goal, start);
    if(!r0.error){
        // r0.result.path.reverse();
        return r0;
    }
    let r1 = await _findPathAsync(start, goal);
    return r1;
}