#ifndef ROCKET_H
#define ROCKET_H

#include <string>
#include <vector>
#include <memory> // for smart pointers

// Forward declarations to keep compile times fast
class Stage;
class FlightState;
class Environment;

/**
 * @brief Represents a complete rocket vehicle composed of stages, motors, and recovery systems.
 *
 * The Rocket class encapsulates the full vehicle configuration, including mass properties,
 * center of gravity (CG), center of pressure (CP), and stability margin calculations.
 * It is the central object for design, simulation, and flight state management.
 */
class Rocket {
public:
    /**
     * @brief Constructs a new Rocket with a given name.
     * @param name The name of the rocket.
     */
    Rocket(const std::string& name);

    /**
     * @brief Default destructor.
     */
    ~Rocket() = default;

    /**
     * @brief Returns the total mass of the rocket (including all stages and payloads).
     * @return Total mass in kilograms.
     */
    double getTotalMass() const;

    /**
     * @brief Returns the total remaining propellant mass of all motors.
     * @return Propellant mass in kilograms.
     */
    double getTotalPropellantMass() const;

    /**
     * @brief Returns the current center of gravity (CG) of the rocket.
     * @return Distance from reference point (e.g., nose tip) in meters.
     */
    double getCenterOfGravity() const;

    /**
     * @brief Returns the current center of pressure (CP) of the rocket.
     * @return Distance from reference point (e.g., nose tip) in meters.
     */
    double getCenterOfPressure() const;

    /**
     * @brief Calculates the rocket's stability margin.
     *
     * Defined as the normalized distance between CG and CP.
     * Positive margin indicates stable configuration.
     * 
     * @return Stability margin (calibers).
     */
    double getStabilityMargin() const;

    /**
     * @brief Adds a new stage to the rocket.
     * @param stage A unique_ptr to the Stage object to add.
     */
    void addStage(std::unique_ptr<Stage> stage);

    /**
     * @brief Returns a const reference to the list of stages.
     * @return Vector of unique_ptr to Stage objects.
     */
    const std::vector<std::unique_ptr<Stage>>& getStages() const;

    /**
     * @brief Recalculates total mass, CG, CP, and stability margin.
     *
     * Should be called after any modification to the rocket structure.
     */
    void updateMassProperties();

    /**
     * @brief Prepares the rocket for flight simulation.
     *
     * Typically called once at simulation setup to adjust for environmental conditions.
     *
     * @param env The environment (atmospheric conditions) at launch.
     */
    void prepareForFlight(const Environment& env);

    /**
     * @brief Applies a given flight state to the rocket.
     *
     * Intended for advanced simulation stages, including 6-DoF dynamics.
     *
     * @param state The current flight state.
     */
    void applyFlightState(const FlightState& state);

    /**
     * @brief Gets the name of the rocket.
     * @return Rocket name as a constant reference.
     */
    const std::string& getName() const;

    /**
     * @brief Sets the name of the rocket.
     * @param name The new name.
     */
    void setName(const std::string& name);

private:
    std::string name_; ///< Name of the rocket.
    std::vector<std::unique_ptr<Stage>> stages_; ///< List of rocket stages.

    // Cached mass properties (updated by updateMassProperties())
    double totalMass_; ///< Total mass of the rocket [kg].
    double totalPropellantMass_; ///< Total remaining propellant mass [kg].
    double centerOfGravity_; ///< Center of gravity location [m].
    double centerOfPressure_; ///< Center of pressure location [m].
};

#endif // ROCKET_H