#pragma once
#include <string>
#include <memory>
#include <optional>
#include <functional>
#include <cstdint>
#include <Eigen/Core>
#include "render/Renderer.h"

namespace ZL {

	class Renderer;

	struct LoadedGameObject {
		std::shared_ptr<Texture> texture;
		std::shared_ptr<Texture> textureDarklands;
		VertexRenderStruct mesh;
		std::string name;
	};

	struct InteractiveObject {
		LoadedGameObject loadedObject;   // name, texture, mesh
		Eigen::Vector3f position;
		Eigen::Vector3f pivot = Eigen::Vector3f::Zero(); // local-space offset to rotation pivot
		float rotationY = 0.0f;          // Y-axis rotation in radians
		float scale     = 1.0f;          // uniform scale
		float alpha     = 1.0f;          // opacity: 1=opaque, 0=fully transparent
		float interactionRadius;
		bool isActive    = true;
		bool isAnimating = false;        // true while a timed animation is running
		std::string activateFunctionName;

		struct AnimTask {
			enum class Type { Move, Rotate, Scale, Fade } type;
			Eigen::Vector3f startPos;
			float startRotY;
			float startScale;
			Eigen::Vector3f targetPos;
			float targetRotY;
			float targetScale;
			float durationMs;
			float elapsedMs = 0.f;
			std::function<void()> onComplete;
		};

		std::optional<AnimTask> animTask;

		InteractiveObject() : interactionRadius(2.0f) {}

		void moveTo(const Eigen::Vector3f& target, float durationSec, std::function<void()> onComplete = {});
		void rotateTo(float targetRotY, float durationSec, std::function<void()> onComplete = {});
		void scaleTo(float targetScale, float durationSec, std::function<void()> onComplete = {});
		void fadeTo(float targetAlpha, float durationSec, std::function<void()> onComplete = {});
		void update(int64_t deltaMs);
		void draw(Renderer& renderer) const;
		void drawDarklands(Renderer& renderer) const;
	};

} // namespace ZL
