#ifndef EDITSCENE_LUA_ACTION_API_HPP
#define EDITSCENE_LUA_ACTION_API_HPP
#pragma once

#include <lua.hpp>

/**
 * @file LuaActionApi.hpp
 * @brief Lua API for the ActionDatabase singleton.
 *
 * Provides Lua functions to create, query, and manage GOAP actions
 * and goals in the global ActionDatabase singleton.
 *
 * Exposed Lua globals (under the "ecs" table):
 *   ecs.action_db.add_action(name, cost, preconds, effects, behaviorTree) -> nil
 *   ecs.action_db.add_goal(name, priority, target, condition) -> nil
 *   ecs.action_db.remove_action(name) -> bool
 *   ecs.action_db.remove_goal(name) -> bool
 *   ecs.action_db.find_action(name) -> table or nil
 *   ecs.action_db.find_goal(name) -> table or nil
 *   ecs.action_db.list_actions() -> table of action names
 *   ecs.action_db.list_goals() -> table of goal names
 *   ecs.action_db.clear() -> nil
 *
 * Bit Name Management:
 *   ecs.action_db.set_bit_name(index, name) -> nil
 *       Assign a human-readable name to a bit slot (0-63).
 *       Example: ecs.action_db.set_bit_name(0, "has_axe")
 *
 *   ecs.action_db.find_bit_by_name(name) -> index or nil
 *       Look up which bit index a name is assigned to.
 *       Returns nil if the name hasn't been assigned yet.
 *
 *   ecs.action_db.get_bit_name(index) -> name or nil
 *       Get the name assigned to a bit slot, or nil if unassigned.
 *
 *   ecs.action_db.list_bit_names() -> table of { index, name }
 *       Returns an array of all assigned bit names with their indices.
 *
 *   ecs.action_db.auto_assign_bit(name) -> index
 *       Find a bit by name, or auto-assign the first free slot.
 *       Returns the bit index, or -1 if all 64 slots are full.
 *       This is the same logic used internally by readBlackboard()
 *       when it encounters an unknown bit name in preconditions/effects.
 *
 * Bit Name Convention:
 *   Bit names are global across the entire game session. They map
 *   human-readable names (like "has_axe", "is_hungry") to bit indices
 *   (0-63) used in GoapBlackboard preconditions and effects.
 *
 *   You can define bits explicitly at startup:
 *     ecs.action_db.set_bit_name(0, "has_axe")
 *     ecs.action_db.set_bit_name(1, "has_wood")
 *     ecs.action_db.set_bit_name(2, "is_hungry")
 *
 *   Or let them be auto-assigned when you use them in actions:
 *     ecs.action_db.add_action("chop_wood", 2,
 *       { bits = { has_axe = true } },  -- "has_axe" auto-assigned if new
 *       { bits = { has_wood = true } })
 *
 *   Use auto_assign_bit() to explicitly reserve a name:
 *     local idx = ecs.action_db.auto_assign_bit("my_flag")
 *     -- idx is now the bit index for "my_flag"
 *
 *   Use list_bit_names() to see all currently assigned names:
 *     local bits = ecs.action_db.list_bit_names()
 *     for _, b in ipairs(bits) do
 *       print(b.index .. ": " .. b.name)
 *     end
 *
 * Behavior Tree Table Format (arg 5 of add_action):
 *   {
 *     type = "sequence",           -- node type: sequence, selector, invert, task, check, etc.
 *     name = "optional_name",      -- action/condition name, animation state, etc.
 *     params = "optional_params",  -- extra parameters (e.g. delay seconds, bit index)
 *     children = {                 -- array of child nodes (for sequence/selector/invert)
 *       { type = "task", name = "myAction" },
 *       { type = "setAnimationState", name = "SM/Walk" },
 *       { type = "delay", params = "2.0" }
 *     }
 *   }
 *
 * See BehaviorTree.hpp for full list of node types.
 */

namespace editScene
{

/**
 * @brief Register all ActionDatabase-related Lua API functions.
 *
 * Adds action_db sub-table to the "ecs" global table.
 * Must be called after LuaState is constructed.
 *
 * @param L The Lua state.
 */
void registerLuaActionApi(lua_State *L);

} // namespace editScene

#endif // EDITSCENE_LUA_ACTION_API_HPP
