#include "LodSettingsEditor.hpp"
#include <imgui.h>
#include <cstring>

void LodSettingsEditor::renderLodLevel(LodLevelConfig& level, int index)
{
	ImGui::PushID(index);
	
	if (ImGui::TreeNode("Level", "LOD Level %d", index + 1)) {
		// Distance
		if (ImGui::DragFloat("Distance", &level.distance, 1.0f, 0.0f, 10000.0f)) {
			// Mark settings as dirty through parent
		}
		
		// Manual mesh option
		if (ImGui::Checkbox("Use Manual Mesh", &level.useManualMesh)) {
			//
		}
		
		if (level.useManualMesh) {
			char meshName[256];
			std::strncpy(meshName, level.manualMeshName.c_str(), sizeof(meshName) - 1);
			meshName[sizeof(meshName) - 1] = '\0';
			if (ImGui::InputText("Mesh Name", meshName, sizeof(meshName))) {
				level.manualMeshName = meshName;
			}
		} else {
			// Reduction method
			const char* methods[] = { "Proportional", "Constant", "Collapse Cost" };
			int currentMethod = static_cast<int>(level.reductionMethod);
			if (ImGui::Combo("Method", &currentMethod, methods, IM_ARRAYSIZE(methods))) {
				level.reductionMethod = static_cast<LodLevelConfig::ReductionMethod>(currentMethod);
			}
			
			// Reduction value
			switch (level.reductionMethod) {
				case LodLevelConfig::ReductionMethod::Proportional:
					if (ImGui::SliderFloat("Reduction %", &level.reductionValue, 0.0f, 1.0f, "%.2f")) {
						//
					}
					ImGui::TextDisabled("0.0 = no reduction, 1.0 = all vertices removed");
					break;
					
				case LodLevelConfig::ReductionMethod::Constant:
					if (ImGui::DragInt("Vertices to Remove", reinterpret_cast<int*>(&level.reductionValue), 1, 0, 100000)) {
						//
					}
					break;
					
				case LodLevelConfig::ReductionMethod::CollapseCost:
					if (ImGui::DragFloat("Max Collapse Cost", &level.reductionValue, 0.1f, 0.0f, 1000.0f)) {
						//
					}
					break;
			}
		}
		
		// Remove button
		if (ImGui::Button("Remove Level")) {
			// This is tricky with ImGui - we mark for removal instead
			level.distance = -1.0f;  // Mark for removal
		}
		
		ImGui::TreePop();
	}
	
	ImGui::PopID();
}

bool LodSettingsEditor::renderComponent(flecs::entity entity, LodSettingsComponent &settings)
{
	bool modified = false;

	if (ImGui::CollapsingHeader("LOD Settings", ImGuiTreeNodeFlags_DefaultOpen)) {
		ImGui::Indent();
		
		// Settings ID (for referencing from LOD components)
		char idBuffer[256];
		std::strncpy(idBuffer, settings.settingsId.c_str(), sizeof(idBuffer) - 1);
		idBuffer[sizeof(idBuffer) - 1] = '\0';
		if (ImGui::InputText("Settings ID", idBuffer, sizeof(idBuffer))) {
			settings.settingsId = idBuffer;
			// Note: We don't mark dirty here as this doesn't affect LOD generation
			modified = true;
		}
		if (ImGui::IsItemHovered()) {
			ImGui::SetTooltip("Unique identifier used by LOD components to reference these settings");
		}
		
		// Auto-generate ID button if empty
		if (settings.settingsId.empty()) {
			if (ImGui::Button("Generate ID")) {
				settings.settingsId = "lod_settings_" + std::to_string(entity.id());
				modified = true;
			}
		}
		
		ImGui::Separator();
		
		// Strategy selector
		const char* strategies[] = { "Distance", "Pixel Count", "Edge Pixel Count" };
		int currentStrategy = static_cast<int>(settings.strategy);
		if (ImGui::Combo("Strategy", &currentStrategy, strategies, IM_ARRAYSIZE(strategies))) {
			settings.strategy = static_cast<LodSettingsComponent::Strategy>(currentStrategy);
			settings.markDirty();
			modified = true;
		}
		
		ImGui::Separator();
		
		// LOD Levels
		ImGui::Text("LOD Levels (%zu configured):", settings.lodLevels.size());
		
		// Remove marked levels
		settings.lodLevels.erase(
			std::remove_if(settings.lodLevels.begin(), settings.lodLevels.end(),
				[](const LodLevelConfig& level) { return level.distance < 0.0f; }),
			settings.lodLevels.end());
		
		// Render levels
		for (size_t i = 0; i < settings.lodLevels.size(); i++) {
			bool levelModified = false;
			float oldDistance = settings.lodLevels[i].distance;
			
			renderLodLevel(settings.lodLevels[i], static_cast<int>(i));
			
			if (settings.lodLevels[i].distance != oldDistance) {
				levelModified = true;
			}
			
			if (levelModified) {
				settings.markDirty();
				modified = true;
			}
		}
		
		// Add level button
		if (ImGui::Button("Add LOD Level")) {
			float distance = settings.lodLevels.empty() ? 100.0f : 
				settings.lodLevels.back().distance * 2.0f;
			settings.addProportionalLevel(distance, 0.5f);
			modified = true;
		}
		
		ImGui::SameLine();
		
		// Auto-configure button
		if (ImGui::Button("Reset to Defaults")) {
			settings.createDefaultLevels();
			modified = true;
		}
		
		ImGui::Separator();
		
		// Advanced options
		if (ImGui::TreeNode("Advanced Options")) {
			if (ImGui::Checkbox("Use Compression", &settings.useCompression)) {
				settings.markDirty();
				modified = true;
			}
			ImGui::SetItemTooltip("Compress index buffers for smaller memory footprint");
			
			if (ImGui::Checkbox("Use Vertex Normals", &settings.useVertexNormals)) {
				settings.markDirty();
				modified = true;
			}
			ImGui::SetItemTooltip("Use vertex normals for better quality (slower generation)");
			
			if (ImGui::Checkbox("Prevent Punching Holes", &settings.preventPunchingHoles)) {
				settings.markDirty();
				modified = true;
			}
			
			if (ImGui::Checkbox("Prevent Breaking Lines", &settings.preventBreakingLines)) {
				settings.markDirty();
				modified = true;
			}
			
			if (ImGui::Checkbox("Background Queue", &settings.useBackgroundQueue)) {
				settings.markDirty();
				modified = true;
			}
			ImGui::SetItemTooltip("Generate LODs in background (requires manual injection)");
			
			ImGui::TreePop();
		}
		
		// Info
		ImGui::Separator();
		ImGui::Text("Version: %u", settings.version);
		if (settings.dirty) {
			ImGui::TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f), "Settings modified - will apply to meshes");
		}
		
		ImGui::Unindent();
	}

	return modified;
}
