package com.ai.trackwalker.service;

import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
public class RuleEngine {
    public RuleDecision evaluate(Map<String, Object> result, Map<String, Object> task) {
        String scene = String.valueOf(result.get("scene"));
        String category = String.valueOf(result.get("category"));
        double confidence = toDouble(result.get("confidence"), 0);
        Map<String, Object> measurements = map(result.get("measurements"));

        List<String> hits = new ArrayList<>();
        String severity = "medium";
        boolean createAlarm = false;

        double distance = toDouble(measurements.get("distance_to_track_m"), 9999);
        if (List.of("违法开挖", "塔吊", "烟火").contains(scene) && distance <= 100 && confidence >= 0.65) {
            createAlarm = true;
            severity = "high";
            hits.add("线路100米范围内");
            hits.add("目标置信度达标");
        }
        if (List.of("接触网异物（高危）", "接触网异物", "线缆悬挂异物").contains(scene) && confidence >= 0.70) {
            createAlarm = true;
            severity = "critical";
            hits.add("高危异物");
            hits.add("接触网/线缆 ROI 内识别");
        }
        if ("防洪点精密监测".equals(scene) && toDouble(measurements.get("volume_change_m3"), 0) >= 1) {
            createAlarm = true;
            severity = "high";
            hits.add("体积变化超过1立方米");
        }
        if (List.of("接头严重发热", "杆上设备发热").contains(scene) && toDouble(measurements.get("temperature_c"), 0) >= 75) {
            createAlarm = true;
            severity = "high";
            hits.add("设备温度超过阈值");
        }
        if ("人员入侵".equals(scene) && Boolean.TRUE.equals(measurements.get("in_protected_area")) && !Boolean.TRUE.equals(measurements.get("maintenance_window"))) {
            createAlarm = true;
            severity = "high";
            hits.add("防护网内");
            hits.add("非天窗时间");
        }
        if ("动物防控".equals(scene) && Boolean.TRUE.equals(measurements.get("in_protected_area"))) {
            createAlarm = true;
            hits.add("中大型动物侵入防护网");
        }
        if (List.of("现场规范", "施工合规").contains(scene) && confidence >= 0.65) {
            createAlarm = true;
            hits.add(category);
        }
        if (!createAlarm && confidence >= 0.75) {
            createAlarm = true;
            hits.add("疑似隐患");
            hits.add("置信度达标");
        }

        Map<String, Object> location = Map.of(
                "line_id", task.getOrDefault("line_id", "line-001"),
                "mileage", measurements.getOrDefault("mileage", "K123+456"),
                "distance_to_track_m", distance == 9999 ? "" : distance,
                "geometry", result.getOrDefault("geometry", Map.of())
        );
        if (createAlarm) {
            return new RuleDecision("create_alarm", severity, hits, false, null, location);
        }
        return new RuleDecision("suppress", "low", List.of("低置信度或未命中业务阈值"), true, "低置信度或未命中业务阈值", location);
    }

    @SuppressWarnings("unchecked")
    private static Map<String, Object> map(Object value) {
        return value instanceof Map<?, ?> map ? (Map<String, Object>) map : Map.of();
    }

    private static double toDouble(Object value, double fallback) {
        if (value instanceof Number number) {
            return number.doubleValue();
        }
        if (value instanceof BigDecimal decimal) {
            return decimal.doubleValue();
        }
        try {
            return value == null ? fallback : Double.parseDouble(String.valueOf(value));
        } catch (NumberFormatException e) {
            return fallback;
        }
    }
}
