#ifndef EDITSCENE_TERRAIN_HPP
#define EDITSCENE_TERRAIN_HPP
#pragma once

#include <Ogre.h>
#include <string>
#include <vector>
#include <cstdint>

/**
 * Terrain component — singleton ECS component holding serializable
 * parameters for the Ogre::Terrain-based terrain feature.
 *
 * Only one entity per scene should carry this component.  All runtime
 * Ogre/Jolt objects live in TerrainSystem, not here.
 */
struct TerrainComponent {
	bool enabled = true;

	// Page/tile vertex resolution. Must be 2^n+1 (e.g. 33, 65, 129, 257).
	int terrainSize = 65;

	// Stable unique ID — generated once at component creation, serialized,
	// never changed.  Used as the directory key for binary terrain data.
	uint64_t terrainId = 0;

	// Base binary heightmap resolution. Default 256x256.
	int heightmapSize = 256;

	// World-space size of one Ogre terrain page in units.
	float worldSize = 2000.0f;

	// Maximum geometric error in pixels before a LOD tile splits.
	float maxPixelError = 1.0f;

	// Distance at which the cheap composite map is used.
	float compositeMapDistance = 300.0f;

	// Minimum and maximum batch LOD sizes. Must be 2^n+1 and <= terrainSize.
	int minBatchSize = 17;
	int maxBatchSize = 65;

	// Base heightmap binary file path.
	std::string heightmapFile = "heightmap.bin";

	// Layer texture settings (diffuse+normal pairs).
	struct Layer {
		std::string name;
		std::string diffuseTexture;
		std::string normalTexture;
		float worldSize = 100.0f;
	};
	std::vector<Layer> layers;

	// Road configuration parameters.
	struct RoadConfig {
		std::string roadMeshTemplate = "road_segment.mesh";
		float laneWidth = 3.0f;
		int lanesPerDirection = 1;
		float roadThickness = 0.3f;
		float roadLodDistance = 200.0f;
		float roadVisibilityDistance = 1000.0f;
		std::string roadMaterialName = "RoadMaterial";
	};
	RoadConfig roadConfig;

	// Road network data (node/edge graph).
	struct RoadNode {
		Ogre::Vector3 position;
		float verticalOffset = 0.0f;
		int id = 0;
	};
	struct RoadEdge {
		int nodeA = -1;
		int nodeB = -1;
		float roadLevelA = 0.0f;
		float roadLevelB = 0.0f;
		int lanesPerDirectionOverride = 0;
		int lanesAtoB = 0;
		int lanesBtoA = 0;
		struct RoadSidePrefab {
			std::string prefabPath;
			float edgeT = 0.5f;
			float sideOffset = 5.0f;
			bool leftSide = true;
		};
		std::vector<RoadSidePrefab> sidePrefabs;
	};
	std::vector<RoadNode> roadNodes;
	std::vector<RoadEdge> roadEdges;

	// Auxiliary maps (foliage density, material masks, etc.).
	struct AuxMap {
		std::string name;
		std::string fileName;
		int resolution = 256;
		float defaultValue = 0.0f;
	};
	std::vector<AuxMap> auxMaps;

	// Runtime-only: managed by TerrainSystem. Not serialized.
	bool dirty = true;
	bool rebuildInProgress = false;

	void markDirty() { dirty = true; }
};

#endif // EDITSCENE_TERRAIN_HPP
