#pragma once

#include <string>
#include <memory>
#include <functional>
#include <unordered_map>
#include <vector>

// Forward declarations to avoid includes
namespace warfactory {
    class IWorldGenerationFunction;
}

namespace warfactory {

/**
 * @brief Factory for creating world generation functions by name
 *
 * Allows registration and creation of world generation functions using string identifiers.
 * Uses lazy includes in .cpp to avoid header pollution.
 */
class WorldGenerationFunctionFactory {
private:
    std::unordered_map<std::string, std::function<std::unique_ptr<IWorldGenerationFunction>()>> factory_functions;

public:
    WorldGenerationFunctionFactory() = default;

    /**
     * @brief Create a world generation function by name
     * @param function_name The name of the function to create
     * @return Unique pointer to the created function, or nullptr if not found
     */
    std::unique_ptr<IWorldGenerationFunction> createFunction(const std::string& function_name);

    /**
     * @brief Register a factory function for a specific function name
     * @param function_name The name to register
     * @param factory_func Function that creates the world generation function
     */
    void registerFunction(const std::string& function_name,
                         std::function<std::unique_ptr<IWorldGenerationFunction>()> factory_func);

    /**
     * @brief Check if a function is registered
     * @param function_name The name to check
     * @return true if the function is registered
     */
    bool isRegistered(const std::string& function_name) const;

    /**
     * @brief Get list of all registered function names
     * @return Vector of registered function names
     */
    std::vector<std::string> getRegisteredFunctions() const;

    /**
     * @brief Clear all registered functions
     */
    void clear();

    /**
     * @brief Get number of registered functions
     */
    size_t getRegisteredCount() const;

    // ========================================
    // CONVENIENCE TEMPLATE METHODS
    // ========================================

    /**
     * @brief Register a function type with automatic factory creation
     * @tparam FunctionType The type of function to register (must inherit from IWorldGenerationFunction)
     * @param function_name The name to register
     */
    template<typename FunctionType>
    void registerFunctionType(const std::string& function_name) {
        registerFunction(function_name, []() -> std::unique_ptr<IWorldGenerationFunction> {
            return std::make_unique<FunctionType>();
        });
    }

    /**
     * @brief Register all standard world generation functions
     * Call this once at startup to populate the factory
     */
    void registerStandardFunctions();
};

// ========================================
// REGISTRATION HELPER MACROS
// ========================================

#define REGISTER_WORLD_FUNCTION(factory, name, type) \
    factory.registerFunctionType<type>(name)

#define REGISTER_WORLD_FUNCTION_LAMBDA(factory, name, lambda) \
    factory.registerFunction(name, lambda)

} // namespace warfactory