#ifndef EDITSCENE_LUA_STATE_HPP
#define EDITSCENE_LUA_STATE_HPP
#pragma once

#include <Ogre.h>
#include <lua.hpp>
#include <flecs.h>
#include <string>
#include <vector>

/**
 * @file LuaState.hpp
 * @brief Lua state management for the editScene editor.
 *
 * Manages the Lua virtual machine instance, library loading,
 * script loading from OGRE resource groups, and the custom
 * package.searchers entry that loads Lua modules from
 * the "LuaScripts" resource group.
 *
 * Usage:
 *   LuaState lua;
 *   lua.installLibraryLoader();  // Register custom searcher
 *   lua.lateSetup();             // Load data.lua and run startup
 *   lua.callHandler("event_name", e1, e2);
 */

namespace editScene
{

/**
 * @brief Manages a single lua_State instance.
 *
 * Opens standard Lua libraries (base, table, math, package, string, io)
 * plus LPEG. Installs a custom package.searchers entry that loads
 * .lua files from OGRE's "LuaScripts" resource group.
 *
 * Provides a handler/callback system: Lua scripts can register
 * callback functions via setup_handler(), and C++ code can invoke
 * them with event names and optional entity parameters.
 */
class LuaState {
public:
	/**
	 * @brief Construct a new Lua state.
	 *
	 * Opens all standard libraries and installs the custom
	 * library loader for OGRE resource-based Lua modules.
	 */
	LuaState();

	/**
	 * @brief Destroy the Lua state and close the VM.
	 */
	~LuaState();

	/**
	 * @brief Get the underlying lua_State pointer.
	 */
	lua_State *getState() const
	{
		return L;
	}

	/**
	 * @brief Install the custom library loader into package.searchers.
	 *
	 * Inserts luaLibraryLoader at position 1 of the searchers table
	 * so it takes precedence over the default file-system loader.
	 * This allows Lua's require() to load modules from OGRE resource
	 * archives.
	 */
	void installLibraryLoader();

	/**
	 * @brief Late setup: load data.lua and run initialisation.
	 *
	 * Opens "data.lua" from the "LuaScripts" resource group and
	 * executes it. Also runs a simple inline Lua test snippet.
	 * Called once after the ECS world is fully initialised.
	 */
	void lateSetup();

	/**
	 * @brief Register a Lua callback function for event handling.
	 *
	 * Expects a Lua function on the stack (at index 1).
	 * Stores a reference to it in the registry so it can be
	 * called later via callHandler().
	 *
	 * @return int Reference index (stored internally).
	 */
	int setupHandler();

	/**
	 * @brief Call all registered handlers with an event name.
	 *
	 * @param event The event name string.
	 * @return int 0 on success.
	 */
	int callHandler(const Ogre::String &event);

	/**
	 * @brief Call all registered handlers with an event name and
	 *        two entity IDs.
	 *
	 * Entity IDs are mapped through the global idmap (see LuaEntityApi).
	 *
	 * @param event The event name string.
	 * @param e1    First entity (e.g. subject).
	 * @param e2    Second entity (e.g. object).
	 * @return int  0 on success.
	 */
	int callHandler(const Ogre::String &event, flecs::entity e1,
			flecs::entity e2);

private:
	lua_State *L;

	/** Registry references for registered Lua callback functions. */
	std::vector<int> setupHandlers;

	/**
	 * @brief Custom Lua loader function for OGRE resource-based modules.
	 *
	 * Registered in package.searchers. Translates dots to path
	 * separators, appends ".lua", and loads the file from the
	 * "LuaScripts" OGRE resource group.
	 *
	 * @param L Lua state.
	 * @return int 1 (pushes loaded chunk onto stack) or error.
	 */
	static int luaLibraryLoader(lua_State *L);
};

} // namespace editScene

#endif // EDITSCENE_LUA_STATE_HPP
