//
// Created by sebastian on 08.02.26.
//

#include "ForestTileGenerator.h"

#include "../../../engine/core/ECS/ModelComponent.h"
#include "../../../engine/core/ECS/TransformComponent.h"
#include "../../../engine/renderer/model/AssetManager.h"
#include "glm/detail/func_geometric.inl"


std::vector<EntityID> ForestTileGenerator::generateHexTile(EntityManager& em, Random& random, glm::vec3 tilePos) const {
    int treeCount = random.randomInt(minTreeCount, maxTreeCount);
    std::shared_ptr<TexturedModel> treeModel = AssetManager::getModel("lowPolyTree");
    std::shared_ptr<TexturedModel> treeModel2 = AssetManager::getModel("lowPolyTree2");
    std::vector<std::shared_ptr<TexturedModel>> treeModels = {treeModel, treeModel2};
    std::vector<EntityID> entitiyIDs;
    for (int i = 0; i < treeCount; ++i) {
        glm::vec3 treePos;
        bool validPos = false;

        // versuche zufällige Position, bis Abstand stimmt oder max Versuche erreicht
        int attempts = 0;

        while (!validPos && attempts < maxAttempts) {
            treePos = tilePos;
            treePos.x += random.randomFloat(-hexRadius * 0.5f, hexRadius * 0.5f);
            treePos.z += random.randomFloat(-hexRadius * 0.5f, hexRadius * 0.5f);

            validPos = true;
            for (const auto& otherTreeID : entitiyIDs) {
                const auto otherTree = em.getComponent<TransformComponent>(otherTreeID);
                if (otherTree) {
                    if (glm::distance(treePos, otherTree->position) < minDistance) {
                        validPos = false;
                        break;
                    }
                }

            }
            attempts++;
        }

        if (!validPos) continue; // zu viele Versuche, überspringen

        int treeModelIndex = random.randomInt(0, static_cast<int>(treeModels.size()-1));

        const auto transformComponent = std::make_shared<TransformComponent>(treePos, glm::vec3(0), 1.f);
        const auto modelComponent = std::make_shared<ModelComponent>(treeModels[treeModelIndex]);

        const EntityID entityID = em.createEntity();
        em.addComponent(entityID, transformComponent);
        em.addComponent(entityID, modelComponent);
        entitiyIDs.push_back(entityID);
    }
    return entitiyIDs;
}
