#pragma once

#include <string>
#include <vector>

#include "RecipesConfig.h"  // for RecipeIngredient
#include "ShipLayout.h"     // for PlacedModule

// Build materials and base production time (REQ-BLD-SHIPYARD, REQ-DEF-SCHEMATIC-DROP).
struct ShipSchematic
{
    std::vector<RecipeIngredient> materials;
    double productionTimeSeconds;
};

struct ShipHealth
{
    float hp;  // REQ-SHP-STATS
};

struct ShipMovement
{
    float speed_mps;                   // max linear speed cap, m/s (REQ-SHP-STATS, REQ-SHP-MOVEMENT)
    float mainAcceleration_mpss;       // forward acceleration, m/s²
    float maneuveringAcceleration_mpss;// omnidirectional acceleration, m/s²
    float angularAcceleration_radpss;  // angular acceleration, rad/s²
    float maxRotationSpeed_radps;      // angular velocity cap, rad/s
};

struct ShipSensor
{
    float sensorRange_m;  // REQ-SHP-SENSOR, REQ-SHP-STATS
};

struct ShipDef
{
    std::string id;
    std::vector<std::string> layout;

    ShipSchematic schematic;
    ShipHealth health;
    ShipMovement movement;
    ShipSensor sensor;

    // Module layout used for enemy wave ships (REQ-WAV-DEFAULT-MODULES).
    std::vector<PlacedModule> defaultModules;
};

struct ShipsConfig
{
    std::vector<ShipDef> ships;

    // Returns the definition for the given ship schematic id, or nullptr if the
    // id has no entry in ships.toml.
    const ShipDef* findShipDef(const std::string& id) const
    {
        for (const ShipDef& def : ships)
        {
            if (def.id == id)
            {
                return &def;
            }
        }
        return nullptr;
    }

    // The definition to configure a layout against, or nullptr when there is no layout
    // to configure: no schematic is selected at all (the empty id the "(None)" option
    // sets, REQ-UI-SELECT-OPTIONS), the id names no ship, or the ship defines no layout
    // grid. Every entry to the layout configuration dialog asks this before opening it
    // and the panel asks it before offering the button that opens it, so the dialog
    // cannot appear over a grid with no cells (REQ-MOD-UI-DIALOG, REQ-MOD-UI-PREVIEW,
    // REQ-MOD-UI-AUTO-DIALOG).
    const ShipDef* findLayoutShipDef(const std::string& id) const
    {
        if (id.empty()) { return nullptr; }
        const ShipDef* def = findShipDef(id);
        if (!def || def->layout.empty()) { return nullptr; }
        return def;
    }
};
