#pragma once

#include <chrono>
#include <cstdint>
#include <filesystem>
#include <string>
#include <vector>

namespace radar::processing {

enum class HistoryCommand {
    None,
    RemoveLast,
    ClearAll,
};

struct ProcessingLiveConfig {
    std::string processor_mode = "pass_through";
    float gain_db = 0.0F;
    float phase_deg = 0.0F;
    bool pass_through_fixed_y_enabled = false;
    float pass_through_y_min_db = -100.0F;
    float pass_through_y_max_db = 0.0F;
    std::string bscan_axis = "abs";
    float bscan_cut_m = 0.824F;
    float bscan_max_depth_m = 1.0F;
    float bscan_gain = 1.0F;
    float bscan_start_freq_mhz = 100.0F;
    float bscan_stop_freq_mhz = 8800.0F;
    std::vector<std::uint32_t> gpr_input_positions{};
    std::vector<std::uint32_t> gpr_output_positions{};
    float gpr_min_depth_m = 2.0F;
    float gpr_max_depth_m = 14.0F;
    float gpr_comp_power = 0.2F;
    float gpr_start_freq_mhz = 3000.0F;
    float gpr_stop_freq_mhz = 6000.0F;
    bool gpr_background_subtract_enabled = true;
    std::uint32_t gpr_background_mean_count = 10U;
    std::uint64_t history_command_seq = 0;
    HistoryCommand history_command = HistoryCommand::None;
};

class ProcessingLiveConfigLoader {
  public:
    explicit ProcessingLiveConfigLoader(std::string path);

    [[nodiscard]] auto current() const -> ProcessingLiveConfig;
    [[nodiscard]] auto refresh_if_needed() -> ProcessingLiveConfig;
    [[nodiscard]] auto revision() const -> std::uint64_t;

  private:
    [[nodiscard]] auto read_from_file() const -> ProcessingLiveConfig;

    std::string path_{};
    ProcessingLiveConfig current_{};
    std::filesystem::file_time_type last_write_time_{};
    bool has_last_write_time_ = false;
    std::uint64_t revision_ = 0;
    std::chrono::steady_clock::time_point next_check_at_{};
};

}  // namespace radar::processing
