#pragma once

#include "../Utils.hpp"
#include <string>
#include <Ogre.h>
#include <flecs.h>
#include "ProceduralTexture.hpp"

/**
 * @brief Component for creating procedural Ogre materials
 * 
 * Creates a named material that uses ProceduralTexture as diffuse/albedo map.
 * The material can be referenced by name for use with meshes/entities.
 */
struct ProceduralMaterialComponent {
	// Unique identifier for persistent referencing across scene loads
	std::string materialId;

	// Material name for Ogre resource
	std::string materialName;

	ProceduralMaterialComponent()
	{
		materialId = generatePersistentId();
	}

	// Persistent reference to texture by ID
	std::string diffuseTextureId;

	// Runtime reference to entity with ProceduralTextureComponent (for diffuse)
	flecs::entity diffuseTextureEntity = flecs::entity::null();

	// Whether the material needs regeneration
	bool dirty = true;

	// Whether the material has been created
	bool created = false;

	// Pointer to the created Ogre material
	Ogre::MaterialPtr ogreMaterial;

	// Track texture version for automatic rebuild when texture changes
	unsigned int textureVersion = 0;

	// Material properties
	float ambient[3] = { 0.2f, 0.2f, 0.2f }; // Ambient color (RGB 0-1)
	float diffuse[3] = { 1.0f, 1.0f,
			     1.0f }; // Diffuse color multiplier (RGB 0-1)
	float specular[3] = { 0.0f, 0.0f, 0.0f }; // Specular color (RGB 0-1)
	float shininess = 32.0f; // Specular shininess
	float roughness = 0.5f; // Roughness (0-1, for PBR-style)

	void markDirty()
	{
		dirty = true;
	}

	// Helper to check if texture reference is valid
	bool hasValidTexture() const
	{
		return diffuseTextureEntity.is_alive() &&
		       diffuseTextureEntity.has<ProceduralTextureComponent>();
	}
};
