package com.qaup.collision.rule.event;

import com.qaup.collision.event.service.ThreatLevelEventService;
import com.qaup.collision.rule.model.entity.SpatialRule;
import com.qaup.collision.rule.service.RuleViolationProcessor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;

import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 规则事件监听器
 * 处理各种规则相关事件的核心监听器
 */
@Slf4j
@Component
public class RuleEventListener {

    @Autowired
    private RuleViolationProcessor ruleViolationProcessor;

    @Autowired
    private ThreatLevelEventService threatLevelEventService;

    // 事件处理统计
    private final AtomicLong violationEventCount = new AtomicLong(0);
    private final AtomicLong executionEventCount = new AtomicLong(0);
    private final AtomicLong stateChangeEventCount = new AtomicLong(0);

    /**
     * 处理规则违规事件
     * 同步处理，确保违规事件得到及时响应（简化架构）
     */
    @EventListener
    @Order(1) // 最高优先级
    public void handleViolationEvent(RuleViolationEventOccurred event) {
        try {
            long startTime = System.currentTimeMillis();
            
            log.info("接收到规则违规事件: {}", event.getEventDescription());
            
            RuleViolationEvent violationEvent = event.getViolationEvent();
            
            // 基于威胁级别处理事件通知
            threatLevelEventService.processViolationNotification(violationEvent);
            
            // 违规事件处理
            if (event.isHighPriority() || event.isCriticalEvent()) {
                // 高优先级或紧急事件同步处理
                handleHighPriorityViolation(violationEvent, event);
            } else {
                // 普通违规事件异步处理
                handleNormalViolation(violationEvent, event);
            }
            
            // 更新统计
            violationEventCount.incrementAndGet();
            
            long processingTime = System.currentTimeMillis() - startTime;
            log.debug("违规事件处理完成: vehicleId={}, processingTime={}ms", 
                    violationEvent.getVehicleId(), processingTime);
            
        } catch (Exception e) {
            log.error("处理规则违规事件失败: event={}, error={}", event, e.getMessage(), e);
        }
    }

    /**
     * 处理规则执行事件
     */
    @EventListener
    @Order(2)
    public void handleRuleExecutionEvent(RuleExecutionEvent event) {
        try {
            log.debug("接收到规则执行事件: {}", event.getEventDescription());
            
            switch (event.getEventType()) {
                case EXECUTION_STARTED:
                    handleExecutionStarted(event);
                    break;
                case EXECUTION_COMPLETED:
                    handleExecutionCompleted(event);
                    break;
                case EXECUTION_FAILED:
                    handleExecutionFailed(event);
                    break;
                case EXECUTION_TIMEOUT:
                    handleExecutionTimeout(event);
                    break;
                case EXECUTION_SKIPPED:
                    handleExecutionSkipped(event);
                    break;
                case EXECUTION_RETRIED:
                    handleExecutionRetried(event);
                    break;
                default:
                    log.warn("未知的规则执行事件类型: {}", event.getEventType());
            }
            
            // 更新统计
            executionEventCount.incrementAndGet();
            
        } catch (Exception e) {
            log.error("处理规则执行事件失败: event={}, error={}", event, e.getMessage(), e);
        }
    }

    /**
     * 处理规则状态变更事件
     */
    @EventListener
    @Order(3)
    public void handleRuleStateChangeEvent(RuleStateChangeEvent event) {
        try {
            log.info("接收到规则状态变更事件: {}", event.getEventDescription());
            
            // 根据变更类型进行相应处理
            switch (event.getChangeType()) {
                case ACTIVATION:
                case RESUMPTION:
                    handleRuleActivation(event);
                    break;
                case DEACTIVATION:
                case SUSPENSION:
                    handleRuleDeactivation(event);
                    break;
                case CONFIGURATION_UPDATE:
                    handleRuleConfigUpdate(event);
                    break;
                case EXPIRATION:
                    handleRuleExpiration(event);
                    break;
                case ERROR_TRIGGERED:
                    handleRuleError(event);
                    break;
                default:
                    handleGenericStateChange(event);
            }
            
            // 如果影响运行时，进行额外处理
            if (event.isAffectsRuntime()) {
                handleRuntimeImpactingChange(event);
            }
            
            // 更新统计
            stateChangeEventCount.incrementAndGet();
            
        } catch (Exception e) {
            log.error("处理规则状态变更事件失败: event={}, error={}", event, e.getMessage(), e);
        }
    }

    /**
     * 处理高优先级违规事件
     */
    private void handleHighPriorityViolation(RuleViolationEvent violationEvent, RuleViolationEventOccurred event) {
        log.warn("处理高优先级违规事件: vehicleId={}, 规则={}, priority={}", 
                violationEvent.getVehicleId(), violationEvent.getRuleName(), event.getPriority());
        
        // 立即处理违规事件
        ruleViolationProcessor.processViolationEvent(violationEvent);
        
        // 紧急事件额外处理
        if (event.isCriticalEvent()) {
            handleCriticalViolation(violationEvent, event);
        }
        
        // 记录高优先级事件处理
        recordHighPriorityEventHandling(violationEvent, event);
    }

    /**
     * 处理普通违规事件
     */
    private void handleNormalViolation(RuleViolationEvent violationEvent, RuleViolationEventOccurred event) {
        log.debug("处理普通违规事件: vehicleId={}, 规则={}", 
                violationEvent.getVehicleId(), violationEvent.getRuleName());
        
        // 同步处理违规事件（简化架构）
        ruleViolationProcessor.processViolationEvent(violationEvent);
    }

    /**
     * 处理紧急违规事件
     */
    private void handleCriticalViolation(RuleViolationEvent violationEvent, RuleViolationEventOccurred event) {
        log.error("处理紧急违规事件: vehicleId={}, 规则={}, 违规类型={}", 
                violationEvent.getVehicleId(), violationEvent.getRuleName(), violationEvent.getViolationType());
        
        try {
            // 1. 立即通知相关人员
            log.error("CRITICAL VIOLATION ALERT: 车辆 {} 在规则 {} 发生紧急违规", 
                    violationEvent.getVehicleId(), violationEvent.getRuleName());
            
            // 2. 记录到紧急事件日志（简化实现）
            log.error("EMERGENCY_LOG: eventId={}, vehicleId={}, ruleId={}, location={}, severity={}", 
                    violationEvent.getId(), violationEvent.getVehicleId(), 
                    violationEvent.getRuleName(), violationEvent.getLocation(), 
                    violationEvent.getViolationType());
            
            // 3. 处理紧急响应
            handleEmergencyResponse(violationEvent);
            
        } catch (Exception e) {
            log.error("处理紧急违规事件时发生异常: {}", e.getMessage(), e);
        }
    }

    /**
     * 处理规则执行开始
     */
    private void handleExecutionStarted(RuleExecutionEvent event) {
        log.debug("规则执行开始: ruleId={}, vehicleId={}", 
                event.getRule().getRuleId(), event.getVehicleId());
        
        // 记录执行开始时间，用于性能监控
        recordExecutionStart(event);
    }

    /**
     * 处理规则执行完成
     */
    private void handleExecutionCompleted(RuleExecutionEvent event) {
        log.debug("规则执行完成: ruleId={}, vehicleId={}, result={}, duration={}ms", 
                event.getRule().getRuleId(), event.getVehicleId(), 
                event.getExecutionResult(), event.getExecutionDurationMs());
        
        // 更新性能统计
        updateExecutionStatistics(event);
        
        // 如果执行结果需要进一步处理
        if (event.getExecutionResult() != null && event.getExecutionResult().requiresAction()) {
            handleExecutionResultAction(event);
        }
    }

    /**
     * 处理规则执行失败
     */
    private void handleExecutionFailed(RuleExecutionEvent event) {
        log.warn("规则执行失败: ruleId={}, vehicleId={}, error={}", 
                event.getRule().getRuleId(), event.getVehicleId(), event.getErrorMessage());
        
        // 记录执行失败
        recordExecutionFailure(event);
        
        // 检查是否需要重试
        if (shouldRetryExecution(event)) {
            scheduleExecutionRetry(event);
        }
    }

    /**
     * 处理规则执行超时
     */
    private void handleExecutionTimeout(RuleExecutionEvent event) {
        log.warn("规则执行超时: ruleId={}, vehicleId={}, duration={}ms", 
                event.getRule().getRuleId(), event.getVehicleId(), event.getExecutionDurationMs());
        
        // 记录超时事件
        recordExecutionTimeout(event);
    }

    /**
     * 处理规则执行跳过
     */
    private void handleExecutionSkipped(RuleExecutionEvent event) {
        log.debug("规则执行跳过: ruleId={}, vehicleId={}, details={}", 
                event.getRule().getRuleId(), event.getVehicleId(), event.getExecutionDetails());
    }

    /**
     * 处理规则执行重试
     */
    private void handleExecutionRetried(RuleExecutionEvent event) {
        log.info("规则执行重试: ruleId={}, vehicleId={}", 
                event.getRule().getRuleId(), event.getVehicleId());
    }

    /**
     * 处理规则激活
     */
    private void handleRuleActivation(RuleStateChangeEvent event) {
        log.info("规则激活: ruleId={}, changedBy={}", 
                event.getRule().getRuleId(), event.getChangedBy());
        
        // 规则激活的处理逻辑
        onRuleActivated(event.getRule());
    }

    /**
     * 处理规则停用
     */
    private void handleRuleDeactivation(RuleStateChangeEvent event) {
        log.info("规则停用: ruleId={}, changedBy={}", 
                event.getRule().getRuleId(), event.getChangedBy());
        
        // 规则停用的处理逻辑
        onRuleDeactivated(event.getRule());
    }

    /**
     * 处理规则配置更新
     */
    private void handleRuleConfigUpdate(RuleStateChangeEvent event) {
        log.info("规则配置更新: ruleId={}, changedBy={}", 
                event.getRule().getRuleId(), event.getChangedBy());
        
        // 规则配置更新的处理逻辑
        onRuleConfigUpdated(event.getRule(), event.getChangeContext());
    }

    /**
     * 处理规则过期
     */
    private void handleRuleExpiration(RuleStateChangeEvent event) {
        log.warn("规则过期: ruleId={}", event.getRule().getRuleId());
        
        // 规则过期的处理逻辑
        onRuleExpired(event.getRule());
    }

    /**
     * 处理规则错误
     */
    private void handleRuleError(RuleStateChangeEvent event) {
        log.error("规则错误: ruleId={}, reason={}", 
                event.getRule().getRuleId(), event.getChangeReason());
        
        // 规则错误的处理逻辑
        onRuleError(event.getRule(), event.getChangeReason());
    }

    /**
     * 处理通用状态变更
     */
    private void handleGenericStateChange(RuleStateChangeEvent event) {
        log.debug("规则状态变更: ruleId={}, {} -> {}", 
                event.getRule().getRuleId(), event.getPreviousStatus(), event.getNewStatus());
    }

    /**
     * 处理影响运行时的变更
     */
    private void handleRuntimeImpactingChange(RuleStateChangeEvent event) {
        log.info("检测到影响运行时的规则变更: ruleId={}, changeType={}", 
                event.getRule().getRuleId(), event.getChangeType());
        
        // 通知相关系统更新规则缓存
        notifyRuntimeSystemUpdate(event.getRule());
    }

    // 以下是辅助方法的存根实现，具体实现取决于业务需求
    
    private void handleEmergencyResponse(RuleViolationEvent violationEvent) {
        try {
            log.error("EMERGENCY_RESPONSE: 触发紧急响应程序 - 车辆:{}, 规则:{}, 违规类型:{}", 
                    violationEvent.getVehicleId(), violationEvent.getRuleName(), violationEvent.getViolationType());
            
            // 基本的紧急响应逻辑
            // 1. 记录紧急事件
            // 2. 可以在这里集成第三方告警系统
            // 3. 可以在这里集成无人车控制系统
            
        } catch (Exception e) {
            log.error("执行紧急响应时发生异常: {}", e.getMessage(), e);
        }
    }
    
    private void recordHighPriorityEventHandling(RuleViolationEvent violationEvent, RuleViolationEventOccurred event) {
        log.info("HIGH_PRIORITY_EVENT: id={}, priority={}, processingTime={}", 
                violationEvent.getId(), event.getPriority(), System.currentTimeMillis());
    }
    
    private void recordExecutionStart(RuleExecutionEvent event) {
        log.debug("EXECUTION_START: ruleId={}, vehicleId={}, startTime={}", 
                event.getRule().getRuleId(), event.getVehicleId(), event.getExecutionStartTime());
    }
    
    private void updateExecutionStatistics(RuleExecutionEvent event) {
        long duration = event.getExecutionDurationMs();
        log.debug("EXECUTION_STATS: ruleId={}, duration={}ms, result={}", 
                event.getRule().getRuleId(), duration, event.getExecutionResult());
        
        // 可以在这里更新性能指标到监控系统
        if (duration > 1000) { // 超过1秒的执行时间
            log.warn("SLOW_EXECUTION: ruleId={}, duration={}ms", event.getRule().getRuleId(), duration);
        }
    }
    
    private void handleExecutionResultAction(RuleExecutionEvent event) {
        log.debug("EXECUTION_ACTION: ruleId={}, result={}, requiresAction={}", 
                event.getRule().getRuleId(), event.getExecutionResult(), 
                event.getExecutionResult().requiresAction());
        
        // 根据执行结果执行相应动作
        if (event.getExecutionResult().isViolation()) {
            log.info("VIOLATION_DETECTED: 规则 {} 检测到违规，需要后续处理", event.getRule().getRuleId());
        }
    }
    
    private void recordExecutionFailure(RuleExecutionEvent event) {
        log.error("EXECUTION_FAILURE: ruleId={}, vehicleId={}, error={}, duration={}ms", 
                event.getRule().getRuleId(), event.getVehicleId(), 
                event.getErrorMessage(), event.getExecutionDurationMs());
    }
    
    private boolean shouldRetryExecution(RuleExecutionEvent event) {
        // 简单的重试逻辑：如果是临时错误且执行时间不长，可以重试
        if (event.getErrorMessage() != null && 
            (event.getErrorMessage().contains("timeout") || 
             event.getErrorMessage().contains("connection") ||
             event.getErrorMessage().contains("network"))) {
            return event.getExecutionDurationMs() < 5000; // 执行时间小于5秒才重试
        }
        return false;
    }
    
    private void scheduleExecutionRetry(RuleExecutionEvent event) {
        log.info("EXECUTION_RETRY: 安排规则重试执行 - ruleId={}, vehicleId={}", 
                event.getRule().getRuleId(), event.getVehicleId());
        
        // 这里可以集成调度器来实现重试
        // 简化实现：仅记录重试请求
    }
    
    private void recordExecutionTimeout(RuleExecutionEvent event) {
        log.warn("EXECUTION_TIMEOUT: ruleId={}, vehicleId={}, duration={}ms", 
                event.getRule().getRuleId(), event.getVehicleId(), event.getExecutionDurationMs());
    }
    
    private void onRuleActivated(SpatialRule rule) {
        log.info("RULE_ACTIVATED: ruleId={}, name={}, category={}", 
                rule.getRuleId(), rule.getName(), rule.getCategory());
        
        // 规则激活后的处理逻辑
        // 1. 清除相关缓存
        // 2. 通知其他系统
        // 3. 更新运行时配置
        
        notifyRuntimeSystemUpdate(rule);
    }
    
    private void onRuleDeactivated(SpatialRule rule) {
        log.info("RULE_DEACTIVATED: ruleId={}, name={}, category={}", 
                rule.getRuleId(), rule.getName(), rule.getCategory());
        
        // 规则停用后的处理逻辑
        // 1. 清除相关缓存
        // 2. 停止相关监控
        // 3. 通知其他系统
        
        notifyRuntimeSystemUpdate(rule);
    }
    
    private void onRuleConfigUpdated(SpatialRule rule, java.util.Map<String, Object> changeContext) {
        log.info("RULE_CONFIG_UPDATED: ruleId={}, changes={}", 
                rule.getRuleId(), changeContext != null ? changeContext.keySet() : "unknown");
        
        // 规则配置更新后的处理逻辑
        // 1. 验证新配置
        // 2. 更新缓存
        // 3. 重新加载规则引擎
        
        notifyRuntimeSystemUpdate(rule);
    }
    
    private void onRuleExpired(SpatialRule rule) {
        log.warn("RULE_EXPIRED: ruleId={}, expiredAt={}", 
                rule.getRuleId(), rule.getEffectiveEndTime());
        
        // 规则过期后的处理逻辑
        // 1. 自动停用规则
        // 2. 清理相关数据
        // 3. 发送过期通知
        
        log.info("处理过期规则: {} 的清理工作", rule.getRuleId());
    }
    
    private void onRuleError(SpatialRule rule, String reason) {
        log.error("RULE_ERROR: ruleId={}, reason={}", rule.getRuleId(), reason);
        
        // 规则错误的处理逻辑
        // 1. 记录错误信息
        // 2. 可能需要暂停规则
        // 3. 发送错误告警
        
        if (reason != null && reason.contains("critical")) {
            log.error("CRITICAL_RULE_ERROR: 规则 {} 发生严重错误，建议立即检查", rule.getRuleId());
        }
    }
    
    private void notifyRuntimeSystemUpdate(SpatialRule rule) {
        log.info("RUNTIME_UPDATE: 通知运行时系统更新规则缓存 - ruleId={}", rule.getRuleId());
        
        try {
            // 这里可以集成以下系统的通知：
            // 1. 缓存系统（Redis）
            // 2. 规则引擎
            // 3. 实时监控系统
            // 4. WebSocket通知
            
            // 简化实现：记录更新请求
            log.debug("CACHE_INVALIDATION: 规则 {} 需要更新缓存", rule.getRuleId());
            
        } catch (Exception e) {
            log.error("通知运行时系统更新时发生异常: {}", e.getMessage(), e);
        }
    }

    /**
     * 获取事件处理统计
     */
    public java.util.Map<String, Long> getEventHandlingStatistics() {
        return java.util.Map.of(
                "violationEventCount", violationEventCount.get(),
                "executionEventCount", executionEventCount.get(),
                "stateChangeEventCount", stateChangeEventCount.get(),
                "totalEventCount", violationEventCount.get() + executionEventCount.get() + stateChangeEventCount.get()
        );
    }
} 