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

bool TownEditor::renderComponent(flecs::entity entity, TownComponent& town)
{
    bool modified = false;
    
    if (ImGui::CollapsingHeader("Town", ImGuiTreeNodeFlags_DefaultOpen)) {
        ImGui::Indent();
        
        char nameBuf[128] = {0};
        strncpy(nameBuf, town.townName.c_str(), sizeof(nameBuf) - 1);
        if (ImGui::InputText("Town Name", nameBuf, sizeof(nameBuf))) {
            town.townName = nameBuf;
            modified = true;
        }
        
        // Count districts
        int districtCount = 0;
        entity.children([&](flecs::entity child) {
            if (child.has<DistrictComponent>()) {
                districtCount++;
            }
        });
        ImGui::Text("Districts: %d", districtCount);
        
        ImGui::Separator();
        ImGui::Text("Town Material:");
        
        // Material selector
        flecs::world world = entity.world();
        std::vector<flecs::entity> materialEntities;
        std::vector<std::string> materialNames;
        materialEntities.push_back(flecs::entity::null());
        materialNames.push_back("Use Generated (Color Rects)");
        
        int currentMatIndex = -1;
        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 (town.proceduralMaterialEntity == e) {
                currentMatIndex = (int)materialEntities.size() - 1;
            }
        });
        
        if (currentMatIndex == -1) currentMatIndex = 0;
        
        std::string comboItems;
        for (size_t i = 0; i < materialNames.size(); ++i) {
            if (i > 0) comboItems += '\0';
            comboItems += materialNames[i];
        }
        comboItems += '\0';
        
        int newIndex = currentMatIndex;
        if (ImGui::Combo("Material", &newIndex, comboItems.c_str())) {
            if (newIndex == 0) {
                town.proceduralMaterialEntity = flecs::entity::null();
                town.proceduralMaterialEntityId.clear();
            } else {
                town.proceduralMaterialEntity = materialEntities[newIndex];
                town.proceduralMaterialEntityId = std::to_string(materialEntities[newIndex].id());
            }
            modified = true;
            town.markMaterialDirty();
        }
        
        // Texture rectangle selector
        if (town.proceduralMaterialEntity.is_alive()) {
            flecs::entity textureEntity = flecs::entity::null();
            if (town.proceduralMaterialEntity.has<ProceduralMaterialComponent>()) {
                const auto& mat = town.proceduralMaterialEntity.get<ProceduralMaterialComponent>();
                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;
                    rectNames.push_back("None (use full texture)");
                    
                    int currentRectIndex = -1;
                    for (const auto& pair : namedRects) {
                        rectNames.push_back(pair.first);
                        if (town.textureRectName == pair.first) {
                            currentRectIndex = (int)rectNames.size() - 1;
                        }
                    }
                    
                    if (currentRectIndex == -1) currentRectIndex = 0;
                    
                    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 == 0) {
                            town.textureRectName.clear();
                        } else {
                            town.textureRectName = rectNames[newRectIndex];
                        }
                        modified = true;
                    }
                }
            }
        }
        
        // Color rects
        if (ImGui::CollapsingHeader("Color Rects")) {
            for (auto& [name, rect] : town.colorRects) {
                ImGui::PushID(name.c_str());
                ImGui::Text("%s", name.c_str());
                float l = rect.left, t = rect.top, r = rect.right, b = rect.bottom;
                if (ImGui::SliderFloat("Left", &l, 0.0f, 1.0f)) { rect.left = l; modified = true; town.markMaterialDirty(); }
                if (ImGui::SliderFloat("Top", &t, 0.0f, 1.0f)) { rect.top = t; modified = true; town.markMaterialDirty(); }
                if (ImGui::SliderFloat("Right", &r, 0.0f, 1.0f)) { rect.right = r; modified = true; town.markMaterialDirty(); }
                if (ImGui::SliderFloat("Bottom", &b, 0.0f, 1.0f)) { rect.bottom = b; modified = true; town.markMaterialDirty(); }
                float color[4] = { rect.color.r, rect.color.g, rect.color.b, rect.color.a };
                if (ImGui::ColorEdit4("Color", color)) {
                    rect.color.r = color[0];
                    rect.color.g = color[1];
                    rect.color.b = color[2];
                    rect.color.a = color[3];
                    modified = true;
                    town.markMaterialDirty();
                }
                ImGui::PopID();
            }
            
            // Add new rect
            static char newName[64] = {0};
            ImGui::InputText("New Rect Name", newName, sizeof(newName));
            if (ImGui::Button("Add Color Rect") && strlen(newName) > 0) {
                town.colorRects[newName] = TownComponent::ColorRect();
                modified = true;
                town.markMaterialDirty();
            }
        }
        
        if (modified) {
            town.markDirty();
        }
        
        ImGui::Unindent();
    }
    
    return modified;
}
