//
// Created by sebastian on 24.12.25.
//

#include "GameLayer.h"

#include "../engine/platform/glfw/InputManager.h"
#include "../engine/renderer/Renderer.h"
#include "../engine/renderer/loader/OBJLoader.h"
#include "../engine/renderer/model/TexturedModel.h"
#include "../engine/renderer/textures/ModelTexture.h"
#include "../engine/toolbox/MathUtils.h"
#include "../engine/layer/entities/Light.h"
#include "../engine/renderer/model/AssetManager.h"
#include "hexWorld/HexModelFactory.h"
#include "hexWorld/MapGenerator.h"

GameLayer::GameLayer() :texturedModel(0,0) //Platzhalter, echtes Model kommt in onAttach
{
}

void GameLayer::onAttach()
{
    texturedModel = *OBJLoader::loadModel("assets/dragon/dragon.obj", "assets/dragon/dragon.png", loader);
    entities.push_back(std::make_shared<Entity>(Entity(std::make_shared<TexturedModel>(texturedModel), glm::vec3(0,0,-25), 0,0,0, 1.f)));
    camera = std::make_unique<Camera>();
    light = std::make_unique<Light>(glm::vec3(0,10,0), glm::vec3(1,1,1));
    mousePicker = std::make_unique<MousePicker>(renderer->getProjectionMatrix(), MathUtils::createViewMatrix(*camera));

    //Map Generation
    hexModelDefault = std::make_shared<TexturedModel>(HexModelFactory::createTexturedHexModel(loader, 10.0f, RessourceType::NONE));
    hexModelWood = std::make_shared<TexturedModel>(HexModelFactory::createTexturedHexModel(loader, 10.0f, RessourceType::WOOD));
    hexModelStone = std::make_shared<TexturedModel>(HexModelFactory::createTexturedHexModel(loader, 10.0f, RessourceType::STONE));
    map = std::make_unique<Map>();

    AssetManager::loadModel("lowPolyTree", "assets/trees/lowPolyTree.obj", "assets/trees/lowPolyTree.png", loader);
    AssetManager::loadModel("lowPolyTree2", "assets/trees/tree.obj", "assets/trees/tree.png", loader);

    //treeModel = std::make_unique<TexturedModel>(*OBJLoader::loadModel("assets/trees/lowPolyTree.obj", "assets/trees/lowPolyTree.png", loader));
    //treeEntity = std::make_unique<Entity>(Entity(treeModel, glm::vec3(0,0,0), 0,0,0, 0.5f));
    MapGenerator::generateHexMap(*map, 10,10,10.f, mapEntities);
    printf("Generated Terrain with %lu Tiles!\n", map->tiles.size());

    auto cabinModel = AssetManager::loadModel("cabin", "assets/cabin/cabin.obj", "assets/cabin/cabin.jpg", loader);
    //entities.push_back(std::make_shared<Entity>(Entity(cabinModel, glm::vec3(0,0,0), 0,0,0, 1.f)));
}

void GameLayer::onDetach()
{
    Layer::onDetach();
}

void GameLayer::onUpdate()
{
    mousePicker->update(*camera);
    //printf("Mouse Ray: %f, %f, %f\n", mousePicker->getCurrentRay().x, mousePicker->getCurrentRay().y, mousePicker->getCurrentRay().z);
    glm::vec3 moveDir = glm::vec3(0,0,0);
    if (InputManager::isKeyPressed(GLFW_KEY_W)) moveDir.z -= 1.0f;
    if (InputManager::isKeyPressed(GLFW_KEY_S)) moveDir.z += 1.0f;
    if (InputManager::isKeyPressed(GLFW_KEY_A)) moveDir.x -= 1.0f;
    if (InputManager::isKeyPressed(GLFW_KEY_D)) moveDir.x += 1.0f;


    camera->move(moveDir, 0.5f);

    for (const auto& entity : entities) {
        renderer->submitEntity(entity.get());
    }

    tileInteractionSystem->update(*map, *camera, *mousePicker);
    tileInteractionSystem->handleBuildAction(*map);


    std::vector<HexRenderData> terrainRenderData = map->getTerrainRenderData(hexModelDefault, hexModelWood, hexModelStone);
    for (auto& renderData : terrainRenderData) {
        renderer->submitTerrainTile(&renderData);
    }

    for (HexTile& tile : map->tiles) {
        for (const auto& entity : tile.entitiesOnTile) {
            renderer->submitEntity(entity.get());
        }
        if (tile.building) renderer->submitEntity(tile.building.get());
    }

    renderer->render(*light, *camera);
}


