package com.qaup.collision.rule.service.impl;

import com.qaup.collision.common.model.MovingObject.MovingObjectType;
import com.qaup.collision.rule.event.RuleViolationEvent;
import com.qaup.collision.rule.model.entity.SpatialRule;
import com.qaup.collision.rule.model.enums.RuleCategory;
import com.qaup.collision.rule.model.enums.RuleExecutionResult;
import com.qaup.collision.rule.model.enums.RuleExecutionStatus;
import com.qaup.collision.rule.model.enums.RuleStatus;
import com.qaup.collision.rule.model.enums.RuleAlertLevel;
import com.qaup.collision.rule.model.enums.ViolationType;
import com.qaup.collision.rule.repository.SimpleRuleViolationEventRepository;
import com.qaup.collision.rule.service.RuleExecutionEngine;
import com.qaup.collision.rule.service.SpatialRuleService;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.Point;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 规则执行引擎实现类 - 专门针对无人车的简化版本
 * 
 * 功能：
 * 1. 执行空间规则检测（速度、区域访问、高度、重量等）
 * 2. 记录违规事件到简化的数据库表
 * 3. 发送实时违规通知
 * 
 * @author AI Assistant
 * @version 4.0 - 无人车专用简化版本
 * @since 2025-01-17
 */
@Slf4j
@Service
@Transactional
public class RuleExecutionEngineImpl implements RuleExecutionEngine {

    @Autowired
    private SpatialRuleService spatialRuleService;
    
    @Autowired
    private com.qaup.collision.rule.service.LocationRuleQueryService locationRuleQueryService;

    @Autowired
    private SimpleRuleViolationEventRepository simpleViolationEventRepository;
    
    @Autowired
    private org.springframework.context.ApplicationEventPublisher eventPublisher;

    @PersistenceContext
    private EntityManager entityManager;


    
    // 短期去重缓存：防止同一检测周期内的重复违规
    // 格式：vehicleId:ruleName:violationType -> timestamp
    private final Map<String, Long> recentViolationsCache = new HashMap<>();
    
    // 缓存清理间隔（毫秒）- 每30秒清理一次过期缓存
    private static final long CACHE_CLEANUP_INTERVAL = 30_000L;
    
    // 短期去重时间窗口（毫秒）- 10秒内相同的违规不重复处理
    private static final long SHORT_TERM_DEDUP_WINDOW = 10_000L;
    
    private long lastCacheCleanup = System.currentTimeMillis();

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 检测违规 - 无人车专用版本
     * 
     * @param vehicleId 无人车ID（数据库主键）
     * @param vehicleType 必须是 MovingObjectType.UNMANNED_VEHICLE
     * @param location 当前位置
     * @param vehicleState 车辆状态（包含速度、高度等信息）
     * @param timestamp 检测时间
     * @return 检测结果（始终返回null，实际结果通过数据库记录）
     */
    public Object detectViolationForUnmannedVehicle(String vehicleId, MovingObjectType vehicleType, Point location,
                                 Map<String, Object> vehicleState, LocalDateTime timestamp) {
        // 只处理无人车
        if (vehicleType != MovingObjectType.UNMANNED_VEHICLE) {
            log.debug("跳过非无人车的违规检测: vehicleId={}, type={}", vehicleId, vehicleType);
            return null;
        }
        
        // 将字符串vehicleId转换为Long类型（内部统一使用Long类型的vehicle_id）
        Long vehicleIdLong;
        try {
            vehicleIdLong = Long.parseLong(vehicleId);
        } catch (NumberFormatException e) {
            log.warn("无效的vehicleId格式: {}", vehicleId);
            return null;
        }
        
        log.debug("开始无人车违规检测: vehicleId={}, 位置=[{},{}]", vehicleIdLong, location.getX(), location.getY());

        try {
            // 获取当前位置适用的所有活跃规则 - 使用与检测器一致的服务
            List<SpatialRule> applicableRules = locationRuleQueryService.findApplicableRules(location, vehicleType, timestamp);
            
            log.debug("🔍 规则执行引擎找到适用规则数量: {}", applicableRules.size());
            for (SpatialRule rule : applicableRules) {
                log.debug("📋 找到适用规则: {} - {} ({})", rule.getRuleId(), rule.getName(), rule.getCategory());
            }
            
            if (applicableRules.isEmpty()) {
                log.debug("❌ 无人车 {} 当前位置无适用规则", vehicleIdLong);
                return null;
            }
            
            // 输出车辆状态用于调试
            log.debug("🚗 车辆状态数据: {}", vehicleState);

            // 检查每个适用的规则
            for (SpatialRule rule : applicableRules) {
                if (rule.getStatus() != RuleStatus.ACTIVE) {
                    continue;
                }

                RuleExecutionResult result = executeRuleInternal(rule, vehicleState, location, timestamp);
                
                if (result == RuleExecutionResult.VIOLATION) {
                    // 获取违规类型（用于去重）
                    String violationType = determineViolationType(rule.getCategory());
                    
                    // 检查短期去重：防止同一检测周期内的重复违规
                    if (isRecentViolation(vehicleIdLong, rule.getName(), violationType)) {
                        log.debug("跳过重复违规: vehicleId={}, rule={}, type={}", vehicleIdLong, rule.getName(), violationType);
                        continue;
                    }
                    
                    // 记录违规事件 - 内部基于vehicle_id处理
                    recordViolationEventInNewTransaction(rule, vehicleIdLong, location, vehicleState, timestamp);
                    
                    // 更新去重缓存
                    updateRecentViolationCache(vehicleIdLong, rule.getName(), violationType);
                }
            }

            return null; // 兼容原接口，实际结果通过数据库查询
            
        } catch (Exception e) {
            log.error("无人车违规检测失败: vehicleId={}, 错误={}", vehicleIdLong, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 执行单个规则检查（内部方法）
     */
    private RuleExecutionResult executeRuleInternal(SpatialRule rule, Map<String, Object> vehicleState, 
                                          Point location, LocalDateTime timestamp) {
        try {
            log.debug("执行规则检查: 规则名={}, 类型={}", rule.getName(), rule.getCategory());

            switch (rule.getCategory()) {
                case SPEED_LIMIT:
                    return checkSpeedLimit(rule, vehicleState);
                case ACCESS_CONTROL:
                    return checkAccessControl(rule, vehicleState, location);
                case HEIGHT_LIMIT:
                    return checkHeightLimit(rule, vehicleState);
                case WEIGHT_LIMIT:
                    return checkWeightLimit(rule, vehicleState);
                default:
                    log.debug("未支持的规则类型: {}", rule.getCategory());
                    return RuleExecutionResult.NOT_APPLICABLE;
            }
        } catch (Exception e) {
            log.error("规则执行失败: 规则={}, 错误={}", rule.getName(), e.getMessage());
            return RuleExecutionResult.EXECUTION_ERROR;
        }
    }

    /**
     * 检查速度限制
     */
    private RuleExecutionResult checkSpeedLimit(SpatialRule rule, Map<String, Object> vehicleState) {
        log.debug("🚀 开始检查速度限制 - 规则: {}", rule.getName());
        
        Object speedObj = vehicleState.get("speed");
        log.debug("📊 从车辆状态获取速度数据: {}", speedObj);
        
        if (speedObj == null) {
            log.debug("⚠️ 速度数据为null，规则不适用");
            return RuleExecutionResult.NOT_APPLICABLE;
        }

        double currentSpeed = ((Number) speedObj).doubleValue();
        log.debug("📈 解析后的当前速度: {}km/h", currentSpeed);
        
        try {
            JsonNode parameters = parseJsonString(rule.getParameters());
            log.debug("📝 规则参数: {}", rule.getParameters());
            
            if (!parameters.has("maxSpeed") && !parameters.has("max_speed_kph")) {
                log.warn("⚠️ 规则参数中缺少maxSpeed或max_speed_kph字段");
                return RuleExecutionResult.EXECUTION_ERROR;
            }
            
            // 支持两种字段名称格式
            double speedLimit = parameters.has("maxSpeed") ? 
                parameters.get("maxSpeed").asDouble() : 
                parameters.get("max_speed_kph").asDouble();
            log.debug("🚩 规则限速: {}km/h", speedLimit);
            
            log.debug("🔍 速度对比: 当前={}km/h vs 限速={}km/h, 超速={}", 
                     currentSpeed, speedLimit, currentSpeed > speedLimit);
            
            if (currentSpeed > speedLimit) {
                log.warn("🚨 检测到超速违规: 当前速度={}km/h, 限速={}km/h, 超出={}km/h", 
                        currentSpeed, speedLimit, currentSpeed - speedLimit);
                return RuleExecutionResult.VIOLATION;
            }
            
            log.debug("✅ 速度检查通过: 未超速");
            return RuleExecutionResult.NOT_APPLICABLE;
        } catch (Exception e) {
            log.error("❌ 速度检查失败: {}", e.getMessage(), e);
            return RuleExecutionResult.EXECUTION_ERROR;
        }
    }

    /**
     * 检查区域访问控制
     */
    private RuleExecutionResult checkAccessControl(SpatialRule rule, Map<String, Object> vehicleState, Point location) {
        try {
            // 获取规则参数
            String parametersJson = rule.getParameters();
            if (parametersJson == null || parametersJson.trim().isEmpty()) {
                log.debug("访问控制规则 {} 没有参数配置", rule.getName());
                return RuleExecutionResult.NOT_APPLICABLE;
            }
            
            // 解析JSON参数
            JsonNode parameters = objectMapper.readTree(parametersJson);
            
            // 检查是否允许访问（简化逻辑：如果规则参数中有 "allowAccess": true 则允许访问）
            boolean allowAccess = parameters.has("allowAccess") && parameters.get("allowAccess").asBoolean();
            
            if (allowAccess) {
                log.debug("访问控制规则 {} 允许访问: 位置=[{},{}]", rule.getName(), location.getX(), location.getY());
                return RuleExecutionResult.PASS;
            } else {
                // 默认情况下，如果无人车在受控区域内且没有明确的访问权限，则视为违规
                log.debug("访问控制规则 {} 检测到未授权访问: 位置=[{},{}]", rule.getName(), location.getX(), location.getY());
                return RuleExecutionResult.VIOLATION;
            }
            
        } catch (Exception e) {
            log.error("访问控制检查失败: 规则={}, 错误={}", rule.getName(), e.getMessage());
            return RuleExecutionResult.EXECUTION_ERROR;
        }
    }

    /**
     * 检查高度限制
     */
    private RuleExecutionResult checkHeightLimit(SpatialRule rule, Map<String, Object> vehicleState) {
        Object heightObj = vehicleState.get("height");
        if (heightObj == null) {
            return RuleExecutionResult.NOT_APPLICABLE;
        }

        double currentHeight = ((Number) heightObj).doubleValue();
        
        try {
            JsonNode parameters = parseJsonString(rule.getParameters());
            double heightLimit = parameters.get("max_height_m").asDouble();
            
            if (currentHeight > heightLimit) {
                log.warn("检测到超高: 当前高度={}m, 限高={}m", currentHeight, heightLimit);
                return RuleExecutionResult.VIOLATION;
            }
            
            return RuleExecutionResult.NOT_APPLICABLE;
        } catch (Exception e) {
            log.error("高度检查失败: {}", e.getMessage());
            return RuleExecutionResult.EXECUTION_ERROR;
        }
    }

    /**
     * 检查重量限制
     */
    private RuleExecutionResult checkWeightLimit(SpatialRule rule, Map<String, Object> vehicleState) {
        Object weightObj = vehicleState.get("weight");
        if (weightObj == null) {
            return RuleExecutionResult.NOT_APPLICABLE;
        }

        double currentWeight = ((Number) weightObj).doubleValue();
        
        try {
            JsonNode parameters = parseJsonString(rule.getParameters());
            double weightLimit = parameters.get("max_weight_kg").asDouble();
            
            if (currentWeight > weightLimit) {
                log.warn("检测到超重: 当前重量={}kg, 限重={}kg", currentWeight, weightLimit);
                return RuleExecutionResult.VIOLATION;
            }
            
            return RuleExecutionResult.NOT_APPLICABLE;
        } catch (Exception e) {
            log.error("重量检查失败: {}", e.getMessage());
            return RuleExecutionResult.EXECUTION_ERROR;
        }
    }

    /**
     * 在新事务中记录违规事件 - 避免事务冲突
     */
    private void recordViolationEventInNewTransaction(SpatialRule rule, Long vehicleId, Point location,
                                                     Map<String, Object> vehicleState, LocalDateTime timestamp) {
        try {
            // 直接在当前线程中执行，但使用新事务
            recordViolationEventAsync(rule, vehicleId, location, vehicleState, timestamp);
        } catch (Exception e) {
            log.error("❌ 记录违规事件失败: 规则={}, vehicleId={}, 错误={}", rule.getName(), vehicleId, e.getMessage(), e);
        }
    }

    /**
     * 记录违规事件 - 基于vehicle_id进行内部处理
     */
    private void recordViolationEventAsync(SpatialRule rule, Long vehicleId, Point location,
                                          Map<String, Object> vehicleState, LocalDateTime timestamp) {
        try {
            // 创建无人车专用的违规事件实体
            RuleViolationEvent violation = new RuleViolationEvent();

            // 直接使用vehicle_id，不查询车牌号
            violation.setVehicleId(vehicleId);
            violation.setRuleName(rule.getName());
            violation.setViolationType(mapToSimpleViolationType(rule.getCategory()));

            // 设置告警级别，如果规则中没有设置则使用默认值
            RuleAlertLevel alertLevel = rule.getAlertLevel();
            if (alertLevel == null) {
                // 根据违规类型确定默认告警级别
                alertLevel = getDefaultAlertLevelForViolationType(violation.getViolationType());
                log.warn("规则 {} 的告警级别为空，使用默认级别: {}", rule.getName(), alertLevel);
            }
            violation.setAlertLevel(alertLevel);

            violation.setDescription(generateSimpleDescription(rule, vehicleState));
            violation.setLocation(location);
            violation.setViolationTime(timestamp);

            // 设置数值信息（如速度限制）
            setViolationValues(violation, rule, vehicleState);

            // 保存到数据库
            RuleViolationEvent savedEvent = simpleViolationEventRepository.save(violation);
            log.info("✅ 无人车违规事件已记录: ID={}, vehicleId={}, 规则={}, 类型={}",
                       savedEvent.getId(), vehicleId, rule.getName(), violation.getViolationType());

            // 发布Spring事件给WebSocket系统
            publishViolationEventToWebSocket(savedEvent);

            // 发送简化的通知
            sendSimpleViolationNotification(savedEvent);

        } catch (Exception e) {
            log.error("❌ 记录违规事件失败: 规则={}, vehicleId={}, 错误={}", rule.getName(), vehicleId, e.getMessage(), e);
            // 不重新抛出异常，避免影响主流程
        }
    }

    /**
     * 发布违规事件到WebSocket系统
     */
    private void publishViolationEventToWebSocket(RuleViolationEvent event) {
        try {
            // 创建RuleViolationEventOccurred事件，这会被RuleEventWebSocketPublisher监听
            com.qaup.collision.rule.event.RuleViolationEventOccurred wsEvent = 
                new com.qaup.collision.rule.event.RuleViolationEventOccurred(
                    this, // 事件源
                    event, // 违规事件
                    "RuleExecutionEngine", // 事件源标识
                    "无人车规则违规检测" // 上下文信息
                );
            
            // 发布到Spring事件系统
            eventPublisher.publishEvent(wsEvent);
            
            log.debug("🔔 违规事件已发布到WebSocket系统: eventId={}, vehicleId={}", 
                     event.getId(), event.getVehicleId());
            
        } catch (Exception e) {
            log.error("❌ 发布违规事件到WebSocket系统失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 发送简化的违规通知
     */
    private void sendSimpleViolationNotification(RuleViolationEvent event) {
        try {
            String message = String.format(
                "🚨 无人车违规警告\n" +
                "📋 车辆ID: %s\n" +
                "⚖️  规则: %s\n" +
                "🚫 类型: %s\n" +
                "⏰ 时间: %s", 
                event.getVehicleId(), 
                event.getRuleName(), 
                getViolationTypeDescription(event.getViolationType()), 
                event.getViolationTime().toString()
            );
            
            // 这里可以集成WebSocket通知或其他通知机制
            log.warn("📢 违规通知: {}", message);
            
        } catch (Exception e) {
            log.error("发送违规通知失败: {}", e.getMessage());
        }
    }

    /**
     * 获取违规类型的中文描述（对应数据库约束的违规类型值）
     */
    private String getViolationTypeDescription(String violationType) {
        switch (violationType) {
            case "SPEED": return "超速行驶";
            case "ACCESS": return "未授权进入";
            case "HEIGHT": return "超过高度限制";
            case "WEIGHT": return "超过重量限制";
            case "OTHER": return "其他违规";
            default: return "未知违规";
        }
    }
    
    /**
     * 映射到数据库约束允许的违规类型值
     * 使用 ViolationType 枚举的 getDatabaseValue() 方法
     */
    private String mapToSimpleViolationType(RuleCategory category) {
        ViolationType violationType = ViolationType.fromRuleCategory(category);
        return violationType.getDatabaseValue();
    }
    
    /**
     * 生成简化的描述（针对无人车）
     */
    private String generateSimpleDescription(SpatialRule rule, Map<String, Object> vehicleState) {
        StringBuilder desc = new StringBuilder();
        
        switch (rule.getCategory()) {
            case SPEED_LIMIT:
                Object speed = vehicleState.get("speed");
                if (speed != null) {
                    desc.append("超速: ").append(String.format("%.1f", speed)).append("km/h");
                } else {
                    desc.append("超速违规");
                }
                break;
            case ACCESS_CONTROL:
                desc.append("未授权进入区域");
                break;
            case HEIGHT_LIMIT:
                Object height = vehicleState.get("height");
                if (height != null) {
                    desc.append("超高: ").append(height).append("m");
                } else {
                    desc.append("高度违规");
                }
                break;
            case WEIGHT_LIMIT:
                desc.append("重量违规");
                break;
            default:
                desc.append("违规行为");
                break;
        }
        
        return desc.toString();
    }
    
    /**
     * 设置违规的实际值和限制值（简化版本）
     */
    private void setViolationValues(RuleViolationEvent event, SpatialRule rule, Map<String, Object> vehicleState) {
        try {
            JsonNode parameters = parseJsonString(rule.getParameters());
            
            switch (rule.getCategory()) {
                case SPEED_LIMIT:
                    Object speed = vehicleState.get("speed");
                    if (speed instanceof Number) {
                        event.setActualValue(((Number) speed).doubleValue());
                    }
                    if (parameters != null) {
                        if (parameters.has("maxSpeed")) {
                            event.setLimitValue(parameters.get("maxSpeed").asDouble());
                        } else if (parameters.has("max_speed_kph")) {
                            event.setLimitValue(parameters.get("max_speed_kph").asDouble());
                        }
                    }
                    break;
                    
                case HEIGHT_LIMIT:
                    Object height = vehicleState.get("height");
                    if (height instanceof Number) {
                        event.setActualValue(((Number) height).doubleValue());
                    }
                    if (parameters != null && parameters.has("max_height_m")) {
                        event.setLimitValue(parameters.get("max_height_m").asDouble());
                    }
                    break;
                    
                case WEIGHT_LIMIT:
                    Object weight = vehicleState.get("weight");
                    if (weight instanceof Number) {
                        event.setActualValue(((Number) weight).doubleValue());
                    }
                    if (parameters != null && parameters.has("max_weight_kg")) {
                        event.setLimitValue(parameters.get("max_weight_kg").asDouble());
                    }
                    break;

                case ACCESS_CONTROL:
                case TIME_RESTRICTION:
                case SAFETY_ZONE:
                case VEHICLE_RESTRICTION:
                case PRIORITY_CONTROL:
                case CUSTOM:
                default:
                    // 对于其他类型的规则，不设置数值信息
                    break;
            }
        } catch (Exception e) {
            log.debug("设置违规数值失败（非关键错误）: {}", e.getMessage());
        }
    }

    /**
     * 解析JSON字符串
     */
    private JsonNode parseJsonString(String jsonString) {
        try {
            if (jsonString == null || jsonString.trim().isEmpty()) {
                return objectMapper.createObjectNode();
            }
            return objectMapper.readTree(jsonString);
        } catch (Exception e) {
            log.warn("解析JSON参数失败: {}", e.getMessage());
            return objectMapper.createObjectNode();
        }
    }

    // ===============================================
    // 统计和查询方法（无人车专用）
    // ===============================================

    /**
     * 获取无人车的违规统计
     */
    public Map<String, Object> getUnmannedVehicleViolationStats(String vehicleLicense) {
        Map<String, Object> stats = new HashMap<>();
        
        try {
            // 总违规次数
            Long totalViolations = simpleViolationEventRepository.countByVehicleLicense(vehicleLicense);
            stats.put("totalViolations", totalViolations);
            
            // 超速违规次数
            Long speedViolations = simpleViolationEventRepository.countByVehicleLicenseAndViolationType(vehicleLicense, "SPEED");
            stats.put("speedViolations", speedViolations);
            
            // 访问违规次数
            Long accessViolations = simpleViolationEventRepository.countByVehicleLicenseAndViolationType(vehicleLicense, "ACCESS");
            stats.put("accessViolations", accessViolations);
            
            // 最近的违规记录
            List<RuleViolationEvent> recentViolations = simpleViolationEventRepository
                .findByVehicleLicenseOrderByViolationTimeDesc(vehicleLicense)
                .stream()
                .limit(5)
                .collect(Collectors.toList());
            stats.put("recentViolations", recentViolations);
            
        } catch (Exception e) {
            log.error("获取无人车违规统计失败: 车牌={}, 错误={}", vehicleLicense, e.getMessage());
            stats.put("error", e.getMessage());
        }
        
        return stats;
    }

    /**
     * 获取今日违规统计
     */
    public Long getTodayViolationCount() {
        try {
            // 计算今日的开始和结束时间
            LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();
            LocalDateTime endOfDay = startOfDay.plusDays(1);
            
            return simpleViolationEventRepository.countTodayViolations(startOfDay, endOfDay);
        } catch (Exception e) {
            log.error("获取今日违规统计失败: {}", e.getMessage());
            return 0L;
        }
    }

    // ===============================================
    // 接口要求的方法（简化实现）
    // ===============================================

    @Override
    public RuleExecutionResult executeRule(SpatialRule rule, String vehicleId, MovingObjectType vehicleType,
                                          Point location, Map<String, Object> vehicleState, LocalDateTime timestamp) {
        // 转发到我们的简化检测方法
        if (vehicleType != MovingObjectType.UNMANNED_VEHICLE) {
            return RuleExecutionResult.NOT_APPLICABLE;
        }
        
        return executeRuleInternal(rule, vehicleState, location, timestamp);
    }

    @Override
    public List<RuleExecutionResult> executeRules(List<SpatialRule> rules, String vehicleId, MovingObjectType vehicleType,
                                                  Point location, Map<String, Object> vehicleState, LocalDateTime timestamp) {
        return rules.stream()
                .map(rule -> executeRule(rule, vehicleId, vehicleType, location, vehicleState, timestamp))
                .collect(Collectors.toList());
    }

    @Override
    public List<RuleExecutionResult> executeLocationRules(String vehicleId, MovingObjectType vehicleType,
                                                         Point location, Map<String, Object> vehicleState, 
                                                         LocalDateTime timestamp) {
        if (vehicleType != MovingObjectType.UNMANNED_VEHICLE) {
            return Collections.emptyList();
        }

        try {
            List<SpatialRule> applicableRules = spatialRuleService.findApplicableRules(location, vehicleType);
            return executeRules(applicableRules, vehicleId, vehicleType, location, vehicleState, timestamp);
        } catch (Exception e) {
            log.error("执行位置规则失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    @Override
    public RuleViolationEvent detectViolation(SpatialRule rule, String vehicleId, MovingObjectType vehicleType,
                                             Point location, Map<String, Object> vehicleState, LocalDateTime timestamp) {
        // 使用我们的简化检测方法，但返回null（因为我们使用新的表结构）
        detectViolationForUnmannedVehicle(vehicleId, vehicleType, location, vehicleState, timestamp);
        return null; // 兼容接口要求，实际违规记录在SimpleRuleViolationEvent表中
    }

    @Override
    public List<RuleViolationEvent> detectViolations(List<SpatialRule> rules, String vehicleId, MovingObjectType vehicleType,
                                                     Point location, Map<String, Object> vehicleState, LocalDateTime timestamp) {
        // 使用我们的简化检测方法
        detectViolationForUnmannedVehicle(vehicleId, vehicleType, location, vehicleState, timestamp);
        return Collections.emptyList(); // 兼容接口要求
    }

    @Override
    public List<RuleViolationEvent> detectAllViolations(String vehicleId, MovingObjectType vehicleType,
                                                        Point location, Map<String, Object> vehicleState, 
                                                        LocalDateTime timestamp) {
        // 使用我们的简化检测方法
        detectViolationForUnmannedVehicle(vehicleId, vehicleType, location, vehicleState, timestamp);
        return Collections.emptyList(); // 兼容接口要求
    }

    @Override
    public boolean isRuleApplicable(SpatialRule rule, MovingObjectType vehicleType, LocalDateTime timestamp) {
        // 只对无人车适用
        if (vehicleType != MovingObjectType.UNMANNED_VEHICLE) {
            return false;
        }
        
        // 检查规则状态
        return rule.getStatus() == RuleStatus.ACTIVE;
    }

    @Override
    public boolean isLocationInRuleScope(SpatialRule rule, Point location) {
        // 简化实现：使用SpatialRuleService检查
        try {
            return spatialRuleService.isLocationInArea(location, rule.getSpatialObjectId());
        } catch (Exception e) {
            log.debug("检查位置范围失败: {}", e.getMessage());
            return false;
        }
    }

    @Override
    public boolean isTimeInRuleScope(SpatialRule rule, LocalDateTime timestamp) {
        // 简化实现：检查基本有效期
        if (rule.getEffectiveStartTime() != null && timestamp.isBefore(rule.getEffectiveStartTime())) {
            return false;
        }
        
        if (rule.getEffectiveEndTime() != null && timestamp.isAfter(rule.getEffectiveEndTime())) {
            return false;
        }
        
        return true;
    }

    @Override
    public boolean isVehicleTypeAllowed(SpatialRule rule, MovingObjectType vehicleType) {
        // 简化实现：只允许无人车
        return vehicleType == MovingObjectType.UNMANNED_VEHICLE;
    }

    @Override
    public void recordExecutionHistory(SpatialRule rule, String vehicleId, MovingObjectType vehicleType,
                                     Point location, RuleExecutionStatus executionStatus, 
                                     RuleExecutionResult executionResult, LocalDateTime timestamp,
                                     Map<String, Object> executionDetails) {
        // 简化实现：只记录日志
        log.debug("规则执行历史: 规则={}, 车辆={}, 状态={}, 结果={}", 
                    rule.getName(), vehicleId, executionStatus, executionResult);
    }

    @Override
    public Map<String, Object> getRuleExecutionStatistics(String ruleId, LocalDateTime startTime, LocalDateTime endTime) {
        // 简化实现：返回基本统计
        Map<String, Object> stats = new HashMap<>();
        stats.put("ruleId", ruleId);
        stats.put("startTime", startTime);
        stats.put("endTime", endTime);
        stats.put("executionCount", 0);
        return stats;
    }

    @Override
    public List<Map<String, Object>> getVehicleExecutionHistory(String vehicleId, LocalDateTime startTime, LocalDateTime endTime) {
        // 简化实现：返回空列表
        return Collections.emptyList();
    }

    @Override
    public void preloadRuleData(Point location, double radiusMeters) {
        // 简化实现：空方法
        log.debug("预加载规则数据: 位置=[{},{}], 半径={}m", location.getX(), location.getY(), radiusMeters);
    }

    @Override
    public void clearExecutionCache() {
        // 简化实现：空方法
        log.debug("清理执行缓存");
    }

    @Override
    public Map<String, Object> getExecutionMetrics() {
        // 简化实现：返回基本指标
        Map<String, Object> metrics = new HashMap<>();
        metrics.put("todayViolations", getTodayViolationCount());
        metrics.put("systemType", "UnmannedVehicleOnly");
        return metrics;
    }
    
    /**
     * 根据规则类别确定违规类型
     * 映射到数据库约束允许的值：SPEED, ACCESS, HEIGHT, WEIGHT, OTHER
     */
    private String determineViolationType(RuleCategory category) {
        switch (category) {
            case SPEED_LIMIT:
                return "SPEED";
            case ACCESS_CONTROL:
                return "ACCESS";
            case HEIGHT_LIMIT:
                return "HEIGHT";
            case WEIGHT_LIMIT:
                return "WEIGHT";
            default:
                return "OTHER";
        }
    }

    /**
     * 根据违规类型获取默认告警级别
     * 对应数据库约束的违规类型值：SPEED, ACCESS, HEIGHT, WEIGHT, OTHER
     */
    private RuleAlertLevel getDefaultAlertLevelForViolationType(String violationType) {
        switch (violationType) {
            case "ACCESS":
                return RuleAlertLevel.CRITICAL;
            case "SPEED":
            case "HEIGHT":
            case "WEIGHT":
                return RuleAlertLevel.WARNING;
            case "OTHER":
            default:
                return RuleAlertLevel.INFO;
        }
    }
    
    /**
     * 检查是否为近期违规（短期去重）
     */
    private boolean isRecentViolation(Long vehicleId, String ruleName, String violationType) {
        cleanupExpiredCache();
        
        String cacheKey = String.format("%d:%s:%s", vehicleId, ruleName, violationType);
        Long lastViolationTime = recentViolationsCache.get(cacheKey);
        
        if (lastViolationTime == null) {
            return false;
        }
        
        long currentTime = System.currentTimeMillis();
        return (currentTime - lastViolationTime) < SHORT_TERM_DEDUP_WINDOW;
    }
    
    /**
     * 更新近期违规缓存
     */
    private void updateRecentViolationCache(Long vehicleId, String ruleName, String violationType) {
        String cacheKey = String.format("%d:%s:%s", vehicleId, ruleName, violationType);
        recentViolationsCache.put(cacheKey, System.currentTimeMillis());
    }
    
    /**
     * 清理过期缓存
     */
    private void cleanupExpiredCache() {
        long currentTime = System.currentTimeMillis();
        
        // 只在达到清理间隔时才清理
        if (currentTime - lastCacheCleanup < CACHE_CLEANUP_INTERVAL) {
            return;
        }
        
        lastCacheCleanup = currentTime;
        
        // 移除过期的缓存项
        recentViolationsCache.entrySet().removeIf(entry -> 
            (currentTime - entry.getValue()) > SHORT_TERM_DEDUP_WINDOW
        );
        
        log.debug("清理过期违规缓存，剩余缓存项: {}", recentViolationsCache.size());
    }
} 