#include "DistrictEditor.hpp"
#include "../components/CellGrid.hpp"
#include "../components/ProceduralTexture.hpp"
#include "../components/ProceduralMaterial.hpp"
#include <imgui.h>

bool DistrictEditor::renderComponent(flecs::entity entity, DistrictComponent& district)
{
    bool modified = false;
    
    if (ImGui::CollapsingHeader("District", ImGuiTreeNodeFlags_DefaultOpen)) {
        ImGui::Indent();
        
        if (ImGui::DragFloat("Radius", &district.radius, 1.0f, 10.0f, 500.0f)) {
            modified = true;
        }
        if (ImGui::DragFloat("Elevation", &district.elevation, 0.1f, -10.0f, 10.0f)) {
            modified = true;
        }
        if (ImGui::DragFloat("Height", &district.height, 0.05f, 0.0f, 10.0f)) {
            modified = true;
        }
        if (ImGui::Checkbox("Is Plaza", &district.isPlaza)) {
            modified = true;
            Ogre::LogManager::getSingleton().logMessage(
                "DistrictEditor: Is Plaza changed to " + std::string(district.isPlaza ? "true" : "false") + 
                " for entity " + std::to_string(entity.id()));
        }
        if (ImGui::SliderFloat("Friction", &district.friction, 0.0f, 1.0f, "%.2f")) {
            modified = true;
        }
        
        // District material and texture settings
        ImGui::Separator();
        ImGui::Text("District Material:");
        
        // Material selector
        flecs::world world = entity.world();
        std::vector<flecs::entity> materialEntities;
        std::vector<std::string> materialNames;
        
        int currentMatIndex = -1;
        int noneMatIndex = 0;
        
        materialEntities.push_back(flecs::entity::null());
        materialNames.push_back("Use Town Material");
        
        world.query<ProceduralMaterialComponent>().each([&](flecs::entity e, ProceduralMaterialComponent& mat) {
            materialEntities.push_back(e);
            std::string name = mat.materialName.empty() ? "Material " + std::to_string(e.id()) : mat.materialName;
            materialNames.push_back(name);
            
            if (district.proceduralMaterialEntity == e) {
                currentMatIndex = (int)materialEntities.size() - 1;
            }
        });
        
        if (currentMatIndex == -1) currentMatIndex = noneMatIndex;
        
        std::string matComboItems;
        for (size_t i = 0; i < materialNames.size(); ++i) {
            if (i > 0) matComboItems += '\0';
            matComboItems += materialNames[i];
        }
        matComboItems += '\0';
        
        int newMatIndex = currentMatIndex;
        if (ImGui::Combo("Material", &newMatIndex, matComboItems.c_str())) {
            if (newMatIndex == noneMatIndex) {
                district.proceduralMaterialEntity = flecs::entity::null();
                district.proceduralMaterialEntityId.clear();
            } else {
                district.proceduralMaterialEntity = materialEntities[newMatIndex];
                district.proceduralMaterialEntityId = std::to_string(materialEntities[newMatIndex].id());
            }
            modified = true;
        }
        
        // Texture rectangle selector
        if (district.proceduralMaterialEntity.is_alive()) {
                // Find the texture entity from the material
                flecs::entity textureEntity = flecs::entity::null();
                if (district.proceduralMaterialEntity.has<ProceduralMaterialComponent>()) {
                    const auto& mat = district.proceduralMaterialEntity.get<ProceduralMaterialComponent>();
                    // Use the material's diffuse texture entity directly
                    if (mat.diffuseTextureEntity.is_alive()) {
                        textureEntity = mat.diffuseTextureEntity;
                    }
                }
                
                if (textureEntity.is_alive() && textureEntity.has<ProceduralTextureComponent>()) {
                    const auto& texture = textureEntity.get<ProceduralTextureComponent>();
                    const auto& namedRects = texture.getAllNamedRects();
                    
                    if (!namedRects.empty()) {
                        std::vector<std::string> rectNames;
                        int currentRectIndex = -1;
                        int noneRectIndex = 0;
                        
                        rectNames.push_back("None (use full texture)");
                        
                        for (const auto& pair : namedRects) {
                            rectNames.push_back(pair.first);
                            if (district.textureRectName == pair.first) {
                                currentRectIndex = (int)rectNames.size() - 1;
                            }
                        }
                        
                        if (currentRectIndex == -1) currentRectIndex = noneRectIndex;
                        
                        std::string rectComboItems;
                        for (size_t i = 0; i < rectNames.size(); ++i) {
                            if (i > 0) rectComboItems += '\0';
                            rectComboItems += rectNames[i];
                        }
                        rectComboItems += '\0';
                        
                        int newRectIndex = currentRectIndex;
                        if (ImGui::Combo("Texture Rectangle", &newRectIndex, rectComboItems.c_str())) {
                            if (newRectIndex == noneRectIndex) {
                                district.textureRectName.clear();
                            } else {
                                district.textureRectName = rectNames[newRectIndex];
                            }
                            modified = true;
                        }
                    } else {
                        ImGui::TextDisabled("No named rectangles in texture");
                    }
                } else {
                    ImGui::TextDisabled("Material has no associated ProceduralTexture");
                }
            }
        
        // Plaza settings
        if (district.isPlaza) {
            ImGui::Separator();
            ImGui::Text("Plaza uses District Material");
        }
        
        // Count lots
        int lotCount = 0;
        entity.children([&](flecs::entity child) {
            if (child.has<LotComponent>()) {
                lotCount++;
            }
        });
        ImGui::Text("Lots: %d", lotCount);
        
        if (modified) {
            district.markDirty();
            Ogre::LogManager::getSingleton().logMessage(
                "DistrictEditor: markDirty() called for entity " + std::to_string(entity.id()));
        }
        
        ImGui::Unindent();
    }
    
    return modified;
}
