#pragma once

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

namespace radar::processing {

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

enum class LegacyGprMode {
    Point,
    Extended,
};

struct ProcessingLiveConfig {
    std::string processor_mode = "pass_through";
    std::string pass_through_channel = "s21";
    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";
    std::string bscan_channel = "s21";
    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;
    LegacyGprMode legacy_gpr_mode = LegacyGprMode::Point;
    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_range_comp_power = 0.28F;
    float gpr_angle_comp_power = 0.10F;
    float gpr_comp_power = 0.2F;
    std::string gpr_score_mode = "combined";
    float gpr_speed_m_s = 0.0F;
    float gpr_look_angle_deg = 0.0F;
    float gpr_snr_thresh = 4.5F;
    float gpr_snr_comp_max = 25.0F;
    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;
    bool gpr_remove_sidelobe_objects_enabled = true;
    // BP image is computed in the y=imaging_plane_y_m slice of the 3D grid.
    // Default 0 keeps legacy 1D antenna layouts imaging in the antenna plane.
    float gpr_imaging_plane_y_m = 0.0F;
    bool reprocess_current_result = true;
    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_file_text() const -> std::string;

    std::string path_{};
    ProcessingLiveConfig current_{};
    std::string last_json_text_{};
    bool has_last_json_text_ = false;
    std::uint64_t revision_ = 0;
    std::chrono::steady_clock::time_point next_check_at_{};
};

}  // namespace radar::processing
