#pragma once

#include "thermal_types.h"
#include "thermal_preprocessor.h"
#include <opencv2/core.hpp>

class ThermalDetector {
public:
    explicit ThermalDetector(const DetectorConfig& cfg = DetectorConfig{});

    Assessment detect(const PreprocessResult& preprocessed);

    // 可视化
    static cv::Mat draw_detections(const cv::Mat& image, const Assessment& assessment);

private:
    DetectorConfig cfg_;

    // 环境温度估计
    static double estimate_ambient(const cv::Mat& temp_map);

    // Pass 1: 人员检测 (体温段)
    std::vector<DetectionResult> detect_persons(const cv::Mat& bands,
                                                const cv::Mat& temp_map,
                                                const cv::Mat& gray) const;

    // Pass 2: 热威胁检测 (热频段)
    std::vector<DetectionResult> detect_thermal_threats(
        const cv::Mat& bands, const cv::Mat& temp_map,
        double ambient, const std::vector<DetectionResult>& persons) const;

    // Pass 3: 冷武器检测
    std::vector<DetectionResult> detect_cold_weapons(
        const cv::Mat& bands, const cv::Mat& temp_map,
        const cv::Mat& gray, const std::vector<DetectionResult>& persons) const;

    // NMS
    std::vector<DetectionResult> nms(const std::vector<DetectionResult>& detections) const;

    // 辅助
    static double compute_iou(const cv::Rect& a, const cv::Rect& b);
    static bool near_person(double cx, double cy,
                            const std::vector<DetectionResult>& persons,
                            double max_ratio);

    double body_temp_score(double mean_temp, double stddev) const;
    double barrel_confidence(double max_temp, double ambient,
                             double solidity, double ar) const;
    double flash_confidence(double max_temp, double circularity, int area) const;

    // 形状特征
    struct ShapeFeatures {
        double aspect_ratio = 0;
        double extent       = 0;
        double solidity     = 0;
        double circularity  = 0;
        bool   is_vertical  = false;
    };
    static ShapeFeatures compute_shape(const cv::Mat& comp_mask, int area,
                                       int x, int y, int w, int h);

    // 温度特征
    struct ThermalFeatures {
        double max_t    = 0;
        double min_t    = 0;
        double mean_t   = 0;
        double stddev_t = 0;
    };
    static ThermalFeatures compute_thermal(const cv::Mat& temp_map,
                                           const cv::Mat& comp_mask,
                                           double ambient);

    // 宽度一致性 (冷武器检测)
    static double check_width_consistency(const cv::Mat& comp_mask, int cw, int ch);
};
