using Godot;
using System;
using System.Linq;
using System.Threading.Tasks;
using Godot.Collections;

public partial class TilemapAvoidance : TileMapLayer
{
    [Export] private Array<TileMapLayer> _solidLayers;
    [Export(PropertyHint.Layers2DPhysics)] public uint ObstaclesCollisionMask { get; private set; }

    private bool _needsFullCheck = false;

    public override void _Ready()
    {
        //NavigationServer2D.MapSetEdgeConnectionMargin(this.TileSet.GetRid(), 0f);
        //_ = RefreshNavigationAsync();
        
    }

    private async Task RefreshNavigationAsync()
    {
        await Task.Delay(500);
        _needsFullCheck = true;
        this.NotifyRuntimeTileDataUpdate();
    }

    public void Recalculate(Vector2 position)
    {
        var mapPos = LocalToMap(this.ToLocal(position));
        var tile = GetCellTileData(mapPos);

        tile.SetNavigationPolygon(0, null);

        //_UpdateCells([mapPos], false);
    }

    public override bool _UseTileDataRuntimeUpdate(Vector2I coords)
    {
        // Run this check and return true only if I know the tiles will need to be updated, which means at start.
        // 
        if (_needsFullCheck)
        {
            // var spaceState = GetWorld2D().DirectSpaceState;
            // var globalCoords = ToGlobal(this.MapToLocal(coords));
            // var query = new PhysicsPointQueryParameters2D();
            // query.Position = globalCoords;
            // query.CollisionMask = ObstaclesCollisionMask;
            // query.CollideWithBodies = true;
            // query.CollideWithAreas = true;
            //
            // var result = spaceState.IntersectPoint(query);
            // if (result.Count > 0) return true;
            
            //_needsFullCheck = false;
            return _solidLayers.Aggregate(false,
                (current, layer) => current | layer.GetUsedCellsById(0).Contains(coords));
        }
        else
        {
            return false;
        }
    }

    public override void _TileDataRuntimeUpdate(Vector2I coords, TileData tileData)
    {
        tileData.SetNavigationPolygon(0, null);
    }
}