Entity* AISystem::FilterNearestUnit(Entity* selectedUnit, set<Entity*> units)
{
    Pathfinder* pathfinder = engine->GetContext()->GetPathfinder();

    Entity* nearest = nullptr;
    int pathSize;
    int shortestPathSize = INT_MAX;

    for (Entity* unit : units)
    {
        UnitComponent* uc = dynamic_cast<UnitComponent*>(unit->GetComponent(Component::UNIT));
        vector<Grid> path = pathfinder->FindPurePath(selectedUnit, unit);
        pathSize = static_cast<int>(path.size());

        if (pathSize > 0
            && (
                pathSize < shortestPathSize
                || (pathSize == shortestPathSize && uc->type == Entity::HQ) // if path sizes are equal, favor HQ
                )
            )
        {
            shortestPathSize = pathSize;
            nearest = unit;
        }
    }

    return nearest;
}
bool AISystem::MoveUnitTowardsEnemy(Entity* selectedUnit, Entity* enemy)
{
    World* world = engine->GetContext()->GetWorld();
    Pathfinder* pathfinder = engine->GetContext()->GetPathfinder();

    vector<Grid> path = pathfinder->FindPurePath(selectedUnit, enemy);

    if (path.size() > 0)
    {
        UnitComponent* uc = dynamic_cast<UnitComponent*>(selectedUnit->GetComponent(Component::UNIT));
        PositionComponent* upc = dynamic_cast<PositionComponent*>(selectedUnit->GetComponent(Component::POSITION));

        Grid lastStep = *(path.end() - 1);
        SelectTarget(Graphics::Instance().ToPx(lastStep));

        for (unsigned int i = 0; i <= uc->range_max; i++)
        {
            // last step is enemy unit so selectedUnit should not move there
            // unit should not move closer to enemy then is necessary to attack it
            path.pop_back();

            if (path.size() == 1)
            {
                // path should not disappear entirely
                break; 
            }
        }

        engine->GetContext()->SetGameState(Context::PL_MOVE);

        selectedUnit->Add(new AnimationComponent(path, upc->pos));
        engine->UpdateEntity(selectedUnit);

        return true;
    }
    else
    {
        return false;
    }
}