#ifndef FLIGHTSIMULATOR_H
#define FLIGHTSIMULATOR_H

#include <memory>
#include <vector>

class Rocket;
class Environment;
class ForcesModel;
class FlightState;
class Integrator;

/**
 * @brief Manages the simulation of a rocket flight from launch to landing.
 *
 * The FlightSimulator coordinates the rocket, environment, force models,
 * and numerical integration to simulate rocket flight dynamics over time.
 */
class FlightSimulator {
public:
    /**
     * @brief Constructs a new FlightSimulator.
     * @param rocket Pointer to the rocket to simulate.
     * @param environment Pointer to the launch environment.
     */
    FlightSimulator(std::shared_ptr<Rocket> rocket,
                    std::shared_ptr<Environment> environment);

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

    /**
     * @brief Runs the full flight simulation.
     * @param maxSimulationTime Maximum allowable simulation time (seconds).
     * @param timeStep Initial time step for integration (seconds).
     */
    void run(double maxSimulationTime, double timeStep);

    /**
     * @brief Returns the recorded flight states over time.
     * @return Vector of FlightState snapshots.
     */
    const std::vector<FlightState>& getFlightLog() const;

private:
    std::shared_ptr<Rocket> rocket_; ///< Rocket being simulated.
    std::shared_ptr<Environment> environment_; ///< Atmospheric and gravity conditions.

    std::shared_ptr<ForcesModel> forcesModel_; ///< Computes forces and moments on the rocket.
    std::unique_ptr<Integrator> integrator_; ///< Integrates equations of motion.

    std::vector<FlightState> flightLog_; ///< Time history of flight state snapshots.

    bool hasLaunched_ = false; ///< Have we left the lauch pad/rail?

    /**
     * @brief Initializes simulation (prepare rocket, set initial conditions).
     */
    void initialize();

    /**
     * @brief Advances the simulation by one time step.
     * @param deltaTime The time step size (seconds).
     */
    void step(double deltaTime);

    /**
     * @brief Detects and processes key events (burnout, separation, recovery).
     * @param state Current flight state.
     */
    void handleEvents(FlightState& state);

    /**
     * @brief Checks if simulation termination conditions are met (e.g., landed).
     * @param state Current flight state.
     * @return True if simulation should stop.
     */
    bool checkTermination(const FlightState& state);


    void updateMotors(double deltaTime);
};

#endif // FLIGHTSIMULATOR_H