#pragma once

#include <vector>

namespace dragonx {
namespace ui {

struct ThreadBenchmark {
    enum class Phase { Idle, Starting, WarmingUp, Measuring, Advancing, CoolingDown, Done };

    struct Result {
        int threads = 0;
        double hashrate = 0.0;
    };

    static constexpr float MIN_WARMUP_SECS = 90.0f;
    static constexpr float MAX_WARMUP_SECS = 300.0f;
    static constexpr float MEASURE_SECS = 30.0f;
    static constexpr float COOLDOWN_SECS = 5.0f;
    static constexpr float STABILITY_WINDOW_SECS = 10.0f;
    static constexpr float STABILITY_THRESHOLD = 0.05f;
    static constexpr int STABLE_WINDOWS_NEEDED = 3;

    Phase phase = Phase::Idle;
    std::vector<int> candidates;
    int current_index = 0;
    std::vector<Result> results;
    float phase_timer = 0.0f;
    double prev_window_avg = 0.0;
    double window_sum = 0.0;
    int window_samples = 0;
    float window_timer = 0.0f;
    int consecutive_stable = 0;
    double measure_sum = 0.0;
    int measure_samples = 0;
    int optimal_threads = 0;
    double optimal_hashrate = 0.0;
    bool was_pool_running = false;
    int prev_threads = 0;
    float total_warmup_secs = 0.0f;

    void reset();
    void buildCandidates(int maxThreads);
    float avgWarmupSecs() const;
    float perTestSecs() const;
    float totalEstimatedSecs() const;
    float elapsedSecs() const;
    float progress() const;
    void resetStabilityTracking();
    bool active() const;
};

struct ThreadBenchmarkUpdate {
    bool stopPoolMining = false;
    bool startPoolMining = false;
    int startThreads = 0;
    bool saveOptimalThreads = false;
    int optimalThreads = 0;
    bool inconclusive = false;  // finished with no nonzero hashrate sample — caller should warn
};

ThreadBenchmarkUpdate AdvanceThreadBenchmark(ThreadBenchmark& benchmark,
                                             float deltaSeconds,
                                             double poolHashrate10s);

} // namespace ui
} // namespace dragonx
