#pragma once

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

// ── 威胁类型 ──
enum class ThreatType {
    PERSON,
    BARREL_OVERHEAT,
    FLASH_RESIDUE,
    ANOMALY_HOTSPOT,
    COLD_WEAPON,
};

struct ThreatTypeInfo {
    static const char* label(ThreatType t) {
        switch (t) {
            case ThreatType::PERSON:          return "Person";
            case ThreatType::BARREL_OVERHEAT: return "Barrel Overheat";
            case ThreatType::FLASH_RESIDUE:   return "Flash Residue";
            case ThreatType::ANOMALY_HOTSPOT: return "Hotspot";
            case ThreatType::COLD_WEAPON:     return "Cold Weapon";
        }
        return "Unknown";
    }
    static cv::Scalar color(ThreatType t) {
        switch (t) {
            case ThreatType::PERSON:          return {0, 255, 0};
            case ThreatType::BARREL_OVERHEAT: return {0, 80, 255};
            case ThreatType::FLASH_RESIDUE:   return {0, 200, 255};
            case ThreatType::ANOMALY_HOTSPOT: return {0, 255, 255};
            case ThreatType::COLD_WEAPON:     return {200, 100, 255};
        }
        return {200, 200, 200};
    }
};

// ── 威胁等级 ──
enum class ThreatLevel {
    SAFE,
    CAUTION,
    WARNING,
    DANGER,
    CRITICAL,
    SUSPECTED_FIRE,
};

struct ThreatLevelInfo {
    static const char* label(ThreatLevel l) {
        switch (l) {
            case ThreatLevel::SAFE:          return "Safe";
            case ThreatLevel::CAUTION:       return "Caution";
            case ThreatLevel::WARNING:       return "Warning";
            case ThreatLevel::DANGER:        return "Danger";
            case ThreatLevel::CRITICAL:      return "Critical";
            case ThreatLevel::SUSPECTED_FIRE: return "Suspected Fire";
        }
        return "Unknown";
    }
    static cv::Scalar color(ThreatLevel l) {
        switch (l) {
            case ThreatLevel::SAFE:          return {0, 200, 0};
            case ThreatLevel::CAUTION:       return {0, 220, 220};
            case ThreatLevel::WARNING:       return {0, 160, 255};
            case ThreatLevel::DANGER:        return {0, 100, 255};
            case ThreatLevel::CRITICAL:      return {0, 0, 200};
            case ThreatLevel::SUSPECTED_FIRE: return {128, 0, 200};
        }
        return {200, 200, 200};
    }
    static bool is_dangerous(ThreatLevel l) {
        return l == ThreatLevel::WARNING
            || l == ThreatLevel::DANGER
            || l == ThreatLevel::CRITICAL
            || l == ThreatLevel::SUSPECTED_FIRE;
    }
};

// ── 检测结果 ──
struct DetectionResult {
    ThreatType type;
    double confidence;
    cv::Rect bbox;
    cv::Point2d centroid;
    double max_temp  = 0;
    double mean_temp = 0;
    int area         = 0;
    double aspect_ratio = 0;
};

// ── 整体评估 ──
struct Assessment {
    std::vector<DetectionResult> detections;
    std::vector<DetectionResult> persons;
    std::vector<DetectionResult> barrels;
    std::vector<DetectionResult> flashes;
    std::vector<DetectionResult> hotspots;
    std::vector<DetectionResult> cold_weapons;
    double ambient_temp   = 0;
    double threshold_temp = 0;

    ThreatLevel level() const {
        bool has_p  = !persons.empty();
        bool has_b  = !barrels.empty();
        bool has_f  = !flashes.empty();
        bool has_cw = !cold_weapons.empty();

        if (has_p && has_b)  return ThreatLevel::CRITICAL;
        if (has_p && has_cw) return ThreatLevel::CRITICAL;
        if (has_p && flashes.size() >= 2) return ThreatLevel::SUSPECTED_FIRE;
        if (has_p)           return ThreatLevel::WARNING;
        if (has_b)           return ThreatLevel::DANGER;
        if (has_cw)          return ThreatLevel::CAUTION;
        if (!hotspots.empty()) return ThreatLevel::CAUTION;
        return ThreatLevel::SAFE;
    }

    bool is_dangerous() const {
        return ThreatLevelInfo::is_dangerous(level());
    }
};

// ── 检测配置 ──
struct DetectorConfig {
    // 人员
    int    person_min_area       = 800;
    double person_max_area_ratio = 0.04;
    double person_ar_min         = 1.0;
    double person_solidity_min   = 0.25;
    double person_fill_min       = 0.20;
    double person_temp_min       = 15.0;
    double person_temp_max       = 60.0;
    int    max_persons           = 8;

    // 枪管
    double barrel_ar_min        = 2.5;
    double barrel_ar_max        = 12.0;
    double barrel_temp_min      = 55.0;
    double barrel_solidity_min  = 0.35;
    double barrel_proximity_ratio = 2.0;

    // 冷武器
    double cold_weapon_ar_min     = 2.0;
    double cold_weapon_ar_max     = 10.0;
    double cold_weapon_thin_ratio = 0.15;
    int    cold_weapon_min_length = 15;
    double cold_weapon_width_cv   = 0.35;

    // 闪光
    int    flash_area_max         = 400;
    double flash_temp_min         = 90.0;
    double flash_circularity_min  = 0.5;

    // 热点
    double hotspot_temp_offset      = 25.0;
    int    hotspot_min_area         = 150;
    int    hotspot_max_area         = 3000;
    double hotspot_min_confidence   = 0.85;
    int    hotspot_max_count        = 2;
    double hotspot_absolute_min_temp = 50.0;

    // 通用
    double confidence_threshold = 0.45;
    double nms_iou_threshold    = 0.35;
};
