#pragma once

#include <optional>
#include <string>
#include <vector>

#include "RecipesConfig.h"

// A single stat modifier contributed by a module instance.
// REQ-MOD-STAT-CALC: final = base * (1 + sum(m_i - 1)) + sum(additives).
struct ModuleStatModifier
{
    std::string stat;         // e.g. "hp", "speed", "sensor_range"
    std::string modifierType; // "additive" or "multiplicative"
    double value;
};

// Capability sections — present when the module grants that capability.
struct ModuleWeaponCapability
{
    float damage;
    float attackRange_m;
    float attackRate_hz;
};

struct ModuleSalvageCapability
{
    float collectionRange_m;
    float cargoCapacity;
    float collectionRate_hz;
};

struct ModuleRepairCapability
{
    float repairRate_hz;     // repair cycles per second
    float repairAmountHp;    // HP restored per cycle
    float repairRange_m;
};

struct ModuleDef
{
    std::string id;
    std::vector<std::string> surfaceMask;
    std::vector<RecipeIngredient> materials;
    double productionTimeSeconds;
    std::string fillColor;
    std::string glyph;
    std::vector<ModuleStatModifier> statModifiers;

    std::optional<ModuleWeaponCapability>  weaponCapability;
    std::optional<ModuleSalvageCapability> salvageCapability;
    std::optional<ModuleRepairCapability>  repairCapability;

    // Optional hover-tooltip text for the module selection button
    // (REQ-MOD-UI-MODULE-TOOLTIP).
    std::optional<std::string> tooltip;
};

struct ModulesConfig
{
    std::vector<ModuleDef> modules;

    // Returns the definition for the given module id, or nullptr if the id has
    // no entry in modules.toml.
    const ModuleDef* findModuleDef(const std::string& id) const
    {
        for (const ModuleDef& def : modules)
        {
            if (def.id == id)
            {
                return &def;
            }
        }
        return nullptr;
    }
};
