#pragma once

#include <opencv2/core.hpp>
#include <string>

enum class ColormapType {
    WHITEHOT,
    BLACKHOT,
    JET,
    IRONBOW,
    THERMAL_RGB,
    GRAY,
};

struct PreprocessResult {
    cv::Mat temperature_map;   // float64 温度图 (°C, 自适应范围用于人员检测)
    cv::Mat temperature_map_wide; // float64 宽范围温度图 (°C, 用于热点/枪管检测)
    cv::Mat band_image;        // uint8 三频段图 (B=环境 G=体温 R=热)
    cv::Mat gray_normalized;   // uint8 归一化灰度
    cv::Mat gray_raw;          // uint8 原始灰度（无增强，用于检测）
    ColormapType colormap;
};

class ThermalPreprocessor {
public:
    explicit ThermalPreprocessor(double tmin = -20.0, double tmax = 150.0);

    ColormapType detect_colormap(const cv::Mat& image) const;
    PreprocessResult preprocess(const cv::Mat& image, ColormapType cmap = ColormapType::GRAY, bool enhance = true, bool auto_colorize = true) const;

    // 灰度转彩色热成像
    cv::Mat colorize(const cv::Mat& image, const std::string& palette = "jet", ColormapType cmap = ColormapType::GRAY) const;

    // 温度提取
    cv::Mat extract_temperature(const cv::Mat& image, ColormapType cmap = ColormapType::GRAY) const;

    // 温度频段分解
    cv::Mat to_temperature_bands(const cv::Mat& temp_map) const;

private:
    double tmin_, tmax_;

    // 色板检测辅助
    ColormapType detect_gray_palette(const cv::Mat& gray) const;
    double check_lut_match(const cv::Mat& image, const cv::Mat& lut) const;

    // 温度提取各路径
    cv::Mat gray_to_temp(const cv::Mat& gray) const;
    cv::Mat gray_to_temp_adaptive(const cv::Mat& gray) const;
    cv::Mat lut_inverse_temp(const cv::Mat& image, const cv::Mat& inv_lut, int q) const;
    cv::Mat thermal_rgb_to_temp(const cv::Mat& image) const;

    // LUT 构建
    cv::Mat jet_lut_;
    cv::Mat ironbow_lut_;
    cv::Mat jet_inv_lut_;
    cv::Mat ironbow_inv_lut_;
    int inv_q_;

    static cv::Mat build_colormap_lut(cv::Vec3b (*color_fn)(int));
    static void build_inverse_lut(const cv::Mat& lut_bgr, cv::Mat& inv_out, int& q_out);

    static cv::Vec3b jet_color(int i);
    static cv::Vec3b ironbow_color(int i);
};
