#ifndef EDITSCENE_LUA_BEHAVIOR_TREE_API_HPP
#define EDITSCENE_LUA_BEHAVIOR_TREE_API_HPP
#pragma once

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

/**
 * @file LuaBehaviorTreeApi.hpp
 * @brief Lua API for creating behavior tree nodes that run Lua functions.
 *
 * Provides Lua bindings to register named Lua functions as behavior tree
 * node handlers, and to create behavior tree nodes that invoke those
 * functions during tree evaluation.
 *
 * Exposed Lua globals (under the "ecs" table):
 *   ecs.behavior_tree.register_node(name, function) -> nil
 *       Register a Lua function as a behavior tree node handler.
 *       The function receives (entity_id, params_table) and must return
 *       "success", "failure", or "running".
 *
 *   ecs.behavior_tree.unregister_node(name) -> bool
 *       Remove a previously registered node handler.
 *
 *   ecs.behavior_tree.list_nodes() -> table of registered node names
 *       Returns an array of all registered node handler names.
 *
 *   ecs.behavior_tree.create_node(type, name, params) -> table
 *       Creates a behavior tree node table suitable for use in
 *       ecs.action_db.add_action() behavior trees.
 *
 *       If the first argument matches a registered Lua node handler name,
 *       it creates a luaTask node (backward compatible).
 *       Otherwise, the first argument is the node type string.
 *
 *       Examples:
 *         ecs.behavior_tree.create_node("setAnimationState", "locomotion/walk")
 *           -> { type = "setAnimationState", name = "locomotion/walk" }
 *
 *         ecs.behavior_tree.create_node("delay", "", "2.0")
 *           -> { type = "delay", params = "2.0" }
 *
 *         ecs.behavior_tree.create_node("say_hello", "message=Hi")
 *           -> { type = "luaTask", name = "say_hello", params = "message=Hi" }
 *
 *       Supported node types (see BehaviorTree.hpp for full list):
 *         sequence, selector, invert, task, check, debugPrint,
 *         setAnimationState, isAnimationEnded, setBit, checkBit,
 *         setValue, checkValue, blackboardDump, delay, teleportToChild,
 *         disablePhysics, enablePhysics, sendEvent, hasItem, hasItemByName,
 *         countItem, pickupItem, dropItem, useItem, addItemToInventory,
 *         luaTask
 *
 * Example:
 *   -- Register a Lua node handler
 *   ecs.behavior_tree.register_node("say_hello", function(entity_id, params)
 *       print("Hello from entity " .. entity_id .. "! " .. (params.message or ""))
 *       return "success"
 *   end)
 *
 *   -- Build a behavior tree using both built-in C++ nodes and Lua nodes
 *   ecs.action_db.add_action("greet", 1, {}, {}, {
 *       type = "sequence",
 *       children = {
 *           ecs.behavior_tree.create_node("setAnimationState", "locomotion/walk"),
 *           ecs.behavior_tree.create_node("delay", "", "2.0"),
 *           ecs.behavior_tree.create_node("setAnimationState", "locomotion/idle"),
 *           ecs.behavior_tree.create_node("say_hello", "message=Hello World")
 *       }
 *   })
 *
 *   -- A Lua node that runs for a while:
 *   ecs.behavior_tree.register_node("wait_random", function(entity_id, params)
 *       local bb = ecs.get_component(entity_id, "GoapBlackboard")
 *       if not bb then return "failure" end
 *
 *       local key = "wait_timer_" .. params.timer_key
 *       local dt = ecs.get_delta_time()
 *       bb.floatValues[key] = (bb.floatValues[key] or 0) + dt
 *
 *       local duration = tonumber(params.duration) or 1.0
 *       if bb.floatValues[key] >= duration then
 *           bb.floatValues[key] = nil
 *           ecs.set_component(entity_id, "GoapBlackboard", bb)
 *           return "success"
 *       end
 *       ecs.set_component(entity_id, "GoapBlackboard", bb)
 *       return "running"
 *   end)
 */

namespace editScene
{

/**
 * @brief Register all behavior tree Lua API functions into the "ecs" table.
 *
 * Adds a behavior_tree sub-table to the "ecs" global table with functions
 * for registering Lua node handlers and creating behavior tree nodes.
 *
 * @param L The Lua state.
 */
void registerLuaBehaviorTreeApi(lua_State *L);

/**
 * @brief Get the list of registered Lua node handler names.
 *
 * Used by the behavior tree editor UI to show registered Lua nodes
 * in a dropdown instead of requiring manual entry.
 *
 * @return A vector of registered node handler names.
 */
std::vector<std::string> getRegisteredLuaNodeNames();

/**
 * @brief Call a registered Lua behavior tree node handler.
 *
 * This is the primary evaluation function used by the behavior tree system.
 * It looks up the registered handler by name, pushes entity and params
 * as arguments, calls the Lua function, and interprets the result.
 *
 * @param L_ Pointer to the Lua state (can be nullptr to use global state).
 * @param nodeName The name of the registered node handler.
 * @param entity The flecs entity executing this node.
 * @param params The params string (key=val,key2=val2 format).
 * @return 0 = success, 1 = failure, 2 = running, -1 = error/not found.
 */
int callLuaBehaviorTreeNode(void *L_, const std::string &nodeName,
			    flecs::entity entity, const std::string &params);

/**
 * @brief Convenience overload for calling a registered Lua node handler
 *        with a raw entity ID (for use in tests or contexts without flecs).
 *
 * @param L_ Pointer to the Lua state (can be nullptr to use global state).
 * @param nodeName The name of the registered node handler.
 * @param entityId The raw entity ID.
 * @param params The params string (key=val,key2=val2 format).
 * @return 0 = success, 1 = failure, 2 = running, -1 = error/not found.
 */
int callLuaBehaviorTreeNode(void *L_, const std::string &nodeName,
			    uint64_t entityId, const std::string &params);

} // namespace editScene

#endif // EDITSCENE_LUA_BEHAVIOR_TREE_API_HPP
