#ifndef EDITSCENE_ACTUATOR_SYSTEM_HPP
#define EDITSCENE_ACTUATOR_SYSTEM_HPP
#pragma once

#include <flecs.h>
#include <Ogre.h>
#include <imgui.h>
#include <vector>
#include <string>

class EditorApp;
class BehaviorTreeSystem;
class ItemSystem;

/**
 * System that handles player interaction with Actuator entities
 * and Item entities.
 *
 * In game mode:
 *  - update() finds nearby actuators and items, handles input
 *  - render() draws on-screen circle markers (called in preViewportUpdate after NewFrame)
 *  - Shows "E - ActionName" (or just "E" for multi-action) when in reach
 *  - Shows "E - Pick up [ItemName]" for items
 *  - Handles E press / hold for action activation
 *  - Manages per-actuator cooldowns
 *  - Executes actions via BehaviorTreeSystem directly (no ActionDebug)
 *  - Disables player controls during action execution
 *
 * Items (entities with ItemComponent but no ActuatorComponent) are
 * detected automatically and shown with a "Pick up" prompt. On E press,
 * the item is added to the player's inventory via ItemSystem.
 */
class ActuatorSystem {
public:
	ActuatorSystem(flecs::world &world, Ogre::SceneManager *sceneMgr,
		       EditorApp *editorApp, BehaviorTreeSystem *btSystem);
	~ActuatorSystem();

	/**
	 * Set the ItemSystem for item pickup handling.
	 * Must be called after construction.
	 */
	void setItemSystem(ItemSystem *system)
	{
		m_itemSystem = system;
	}

	void update(float deltaTime);
	void render();

private:
	struct ScreenActuator {
		flecs::entity entity;
		Ogre::Vector2 screenPos;
		float distance;
		float distToScreenCenter;
	};

	Ogre::Vector2 projectToScreen(const Ogre::Vector3 &worldPoint);
	bool isInRange(const Ogre::Vector3 &charPos,
		       const Ogre::Vector3 &objPos, float radius, float height);
	void executeAction(flecs::entity character,
			   flecs::entity actuatorEntity,
			   const Ogre::String &actionName);
	void executeItemAction(flecs::entity character,
			       flecs::entity itemEntity,
			       const Ogre::String &actionName);
	bool isActionComplete(flecs::entity character, float deltaTime);
	void drawActionMenu(flecs::entity actuatorEntity);
	void setPlayerInputLocked(bool locked);

	flecs::world &m_world;
	Ogre::SceneManager *m_sceneMgr;
	EditorApp *m_editorApp;
	BehaviorTreeSystem *m_btSystem;
	ItemSystem *m_itemSystem = nullptr;

	// Cached data between update() and render()
	std::vector<ScreenActuator> m_visibleActuators;
	int m_targetIndex = -1;
	Ogre::String m_labelText;
	ImVec4 m_circleColor;
	float m_distantRadius = 8.0f;
	float m_nearRadius = 14.0f;
	float m_labelFontSize = 14.0f;

	// Multi-action menu state
	bool m_menuOpen = false;
	flecs::entity_t m_menuActuatorId = 0;
	float m_eHoldTime = 0.0f;
	bool m_eWasHeld = false;
	Ogre::String m_pendingActionName;

	// Currently executing action state
	flecs::entity_t m_executingActuatorId = 0;
	flecs::entity_t m_executingCharacterId = 0;
	Ogre::String m_executingActionName;
	bool m_actionFirstFrame = false;
};

#endif // EDITSCENE_ACTUATOR_SYSTEM_HPP
