package com.qaup.collision.datacollector.service;

import com.qaup.collision.common.model.MovingObject;
import com.qaup.collision.common.model.MovingObject.MovingObjectType;
import com.qaup.collision.common.model.Aircraft;
import com.qaup.collision.common.model.AirportVehicle;
import com.qaup.collision.common.model.UnmannedVehicle;
import com.qaup.collision.common.model.AircraftRoute;
import com.qaup.collision.common.service.VehicleLocationService;
import com.qaup.collision.datacollector.dao.DataCollectorDao;
import com.qaup.collision.datacollector.dto.AircraftRouteDTO;
import com.qaup.collision.datacollector.dto.AircraftStatusDTO;
import com.qaup.collision.datacollector.filter.VehicleLocationFilter;
import com.qaup.collision.websocket.event.AircraftRouteUpdateEvent;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.context.ApplicationEventPublisher;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.PrecisionModel;
import com.qaup.collision.datacollector.util.RouteGeometryProcessor;

/**
 * 数据采集服务 - 重构版本
 * 
 * 主要变更：
 * 1. 移除内存存储依赖（MovingObjectRepository）
 * 2. 改为使用PostGIS的VehicleLocationService进行数据持久化
 * 3. 移除dataMap内存缓存
 * 4. 简化数据流程，直接存储到PostGIS数据库
 * 5. 保留定时采集机制和异常处理
 */
@Slf4j
@Service
public class DataCollectorService {

    // 机场数据源相关配置
    @Value("${data.collector.airport-api.endpoints.vehicle}")
    private String airportVehicleEndpoint;

    @Value("${data.collector.airport-api.endpoints.aircraft}")
    private String airportAircraftEndpoint;

    @Value("${data.collector.airport-api.base-url}")
    private String airportBaseUrl;
    
    @Value("${data.collector.disabled:false}")
    private boolean collectorDisabled;
    
    @Value("${data.collector.detection.interval:1000}")
    private long detectionInterval;

    @Autowired
    private DataCollectorDao dataCollectorDao;

    @Autowired
    private VehicleLocationService vehicleLocationService;
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    @Autowired
    private com.qaup.collision.dataprocessing.service.DataProcessingService dataProcessingService; // 注入数据处理服务
    
    @Autowired
    private RouteGeometryProcessor routeGeometryProcessor; // 注入路由几何处理器
    
    @Autowired
    private RoutePersistenceService routePersistenceService; // 注入路由持久化服务
    
    @Autowired
    private VehicleLocationFilter vehicleLocationFilter; // 注入车辆位置过滤器

    private final GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326); // SRID 4326 for WGS84
    
    // 用于缓存所有活跃的MovingObject的最新状态
    private final Map<String, MovingObject> activeMovingObjectsCache = new ConcurrentHashMap<>();
    
    // 初始化时将缓存引用传递给数据处理服务
    @PostConstruct
    public void init() {
        dataProcessingService.setActiveMovingObjectsCache(activeMovingObjectsCache);
        log.info("DataCollectorService 初始化完成，缓存引用已传递给DataProcessingService");
    }

    /**
     * 采集航空器路由和状态数据
     * 
     * 数据来源：机场系统API
     * - 获取航空器状态 (/aircraftStatusController/getAircraftStatus)
     * - 获取进港路由 (/runwayPathPlanningController/findArrTaxiwayByRunwayAndContactCrossAndSeat)
     * - 获取出港路由 (/runwayPathPlanningController/findDepTaxiwayByRunwayAndContactCrossAndSeat)
     * 
     * 说明：此方法用于更新航空器的路由信息，支持CA3456生命周期模拟
     */
    @Scheduled(fixedRateString = "${data.collector.route.interval:5000}")
    public void collectAircraftRouteAndStatus() {
        if (collectorDisabled) {
            return;
        }
        
        try {
            // 获取航空器状态
            AircraftStatusDTO aircraftStatus = dataCollectorDao.getAircraftStatus();
            if (aircraftStatus == null) {
                log.debug("未获取到航空器状态数据");
                return;
            }
            
            log.info("获取到航空器状态: 航班号={}, 类型={}, 跑道={}-{}, 机位={}", 
                    aircraftStatus.getFlightNo(), 
                    aircraftStatus.getType(),
                    aircraftStatus.getInRunway(),
                    aircraftStatus.getOutRunway(),
                    aircraftStatus.getSeat());
            
            // 根据航空器状态类型获取相应的路由数据
            AircraftRouteDTO routeData = getRouteDataByAircraftStatus(aircraftStatus);
            
            if (routeData != null) {
                log.info("获取到{}路由数据: 编码={}, 状态={}", 
                        routeData.getType(), 
                        routeData.getCodes(), 
                        routeData.getStatus());
                
                // 转换DTO为航空器路由对象
                AircraftRoute aircraftRoute = convertToAircraftRoute(routeData);
                
                if (aircraftRoute != null) {
                    // 直接保存路由到数据库，不依赖缓存中的航空器对象
                    saveAircraftRouteToDatabase(aircraftStatus.getFlightNo(), aircraftRoute);
                    
                    // 更新缓存中的航空器路由信息（如果缓存中有对象的话）
                    updateAircraftRouteInCache(aircraftStatus.getFlightNo(), aircraftRoute, aircraftStatus);
                    
                    // 发布WebSocket事件通知前端路由更新
                    publishAircraftRouteUpdateEvent(aircraftStatus.getFlightNo(), aircraftRoute, aircraftStatus);
                }
            }
            
        } catch (Exception e) {
            log.error("采集航空器路由和状态数据异常", e);
        }
    }
    
    /**
     * 将AircraftRouteDTO转换为AircraftRoute对象
     * 使用JTS将多个LineString段合并为单一连续路径
     */
    private AircraftRoute convertToAircraftRoute(AircraftRouteDTO routeDTO) {
        if (routeDTO == null || routeDTO.getGeoPath() == null) {
            return null;
        }
        
        try {
            // 创建路由段列表
            List<AircraftRoute.RouteSegment> routeSegments = new ArrayList<>();
            List<org.locationtech.jts.geom.LineString> lineStringSegments = new ArrayList<>();
            
            if (routeDTO.getGeoPath().getFeatures() != null) {
                for (AircraftRouteDTO.Feature feature : routeDTO.getGeoPath().getFeatures()) {
                    if (feature.getGeometry() != null && feature.getGeometry().getCoordinates() != null) {
                        // 转换坐标格式：从List<List<Double>>到List<Point>
                        List<org.locationtech.jts.geom.Point> points = feature.getGeometry().getCoordinates().stream()
                            .map(coord -> geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(coord.get(0), coord.get(1))))
                            .collect(java.util.stream.Collectors.toList());
                        
                        // 创建路由段
                        AircraftRoute.RouteSegment segment = AircraftRoute.RouteSegment.builder()
                            .code(feature.getProperties() != null ? feature.getProperties().getCode() : "")
                            .coordinates(points)
                            .build();
                        routeSegments.add(segment);
                        
                        // 创建LineString段用于合并
                        if (points.size() >= 2) {
                            org.locationtech.jts.geom.Coordinate[] coords = points.stream()
                                .map(point -> point.getCoordinate())
                                .toArray(org.locationtech.jts.geom.Coordinate[]::new);
                            org.locationtech.jts.geom.LineString lineString = geometryFactory.createLineString(coords);
                            lineStringSegments.add(lineString);
                        }
                    }
                }
            }
            
            // 使用JTS将多个LineString段合并为单一连续路径
            org.locationtech.jts.geom.LineString mergedGeometry = null;
            if (!lineStringSegments.isEmpty()) {
                mergedGeometry = routeGeometryProcessor.mergeLineStrings(lineStringSegments);
                
                if (mergedGeometry != null && routeGeometryProcessor.isValidLineString(mergedGeometry)) {
                    // 可选：简化路径以减少冗余点（容差：1米）
                    mergedGeometry = routeGeometryProcessor.simplifyLineString(mergedGeometry, 1.0);
                    log.info("成功将 {} 个路由段合并为单一路径，总长度: {} 个坐标点", 
                            lineStringSegments.size(), mergedGeometry.getNumPoints());
                } else {
                    log.warn("路由段合并失败或结果无效");
                    mergedGeometry = null;
                }
            }
            
            return AircraftRoute.builder()
                .type(routeDTO.getType())
                .status(routeDTO.getStatus())
                .codes(routeDTO.getCodes())
                .geometry(mergedGeometry) // 使用合并后的单一LineString
                .routeSegments(routeSegments)
                .build();
                
        } catch (Exception e) {
            log.error("转换航空器路由数据失败", e);
            return null;
        }
    }
    
    /**
     * 根据航空器状态获取路由数据
     * 先查询航班的路由参数，然后调用对应的路由接口
     * 
     * @param aircraftStatus 航空器状态
     * @return 路由数据
     */
    private AircraftRouteDTO getRouteDataByAircraftStatus(AircraftStatusDTO aircraftStatus) {
        try {
            String flightNo = aircraftStatus.getFlightNo();
            String routeType = aircraftStatus.getType();
            
            log.info("开始获取航班路由参数: flightNo={}, routeType={}", flightNo, routeType);
            
            // TODO: 调用航班路由参数查询接口获取完整参数
            // 暂时使用现有的aircraftStatus中的参数
            
            if ("IN".equals(routeType)) {
                // 进港状态，获取进港路由
                log.info("查询进港路由: inRunway={}, outRunway={}, contactCross={}, seat={}", 
                        aircraftStatus.getInRunway(),
                        aircraftStatus.getOutRunway(), 
                        aircraftStatus.getContactCross(),
                        aircraftStatus.getSeat());
                
                return dataCollectorDao.getArrivalRoute(
                    aircraftStatus.getInRunway(),
                    aircraftStatus.getOutRunway(),
                    aircraftStatus.getContactCross(),
                    aircraftStatus.getSeat()
                );
            } else if ("OUT".equals(routeType)) {
                // 出港状态，获取出港路由
                log.info("查询出港路由: inRunway={}, outRunway={}, startSeat={}", 
                        aircraftStatus.getInRunway(),
                        aircraftStatus.getOutRunway(),
                        aircraftStatus.getSeat());
                
                return dataCollectorDao.getDepartureRoute(
                    aircraftStatus.getInRunway(),
                    aircraftStatus.getOutRunway(),
                    aircraftStatus.getSeat()
                );
            } else {
                log.warn("未知的航空器状态类型: {}", routeType);
                return null;
            }
            
        } catch (Exception e) {
            log.error("获取航班路由数据异常: flightNo={}, routeType={}", 
                    aircraftStatus.getFlightNo(), aircraftStatus.getType(), e);
            return null;
        }
    }
    
    /**
     * 保存航空器路由到数据库（独立于缓存）
     */
    private void saveAircraftRouteToDatabase(String flightNo, AircraftRoute route) {
        try {
            log.info("开始保存航空器路由到数据库: flightNo={}, type={}", flightNo, route.getType());
            boolean saveSuccess = routePersistenceService.saveAircraftRoute(flightNo, route);
            
            if (saveSuccess) {
                log.info("成功保存航空器路由到数据库: flightNo={}, type={}", flightNo, route.getType());
                
                // TODO: 保存到路由分配表
                // saveRouteAssignment(flightNo, route);
                
            } else {
                log.warn("保存航空器路由到数据库失败: flightNo={}, type={}", flightNo, route.getType());
            }
        } catch (Exception e) {
            log.error("保存航空器路由到数据库异常: flightNo={}, type={}", flightNo, route.getType(), e);
        }
    }
    
    /**
     * 更新缓存中的航空器路由信息（可选操作，不影响路由保存）
     */
    private void updateAircraftRouteInCache(String flightNo, AircraftRoute route, AircraftStatusDTO status) {
        MovingObject cachedAircraft = activeMovingObjectsCache.get(flightNo);
        
        if (cachedAircraft != null && cachedAircraft instanceof Aircraft) {
            Aircraft aircraft = (Aircraft) cachedAircraft;
            
            // 根据航空器状态更新路由
            if ("IN".equals(status.getType())) {
                aircraft.setArrivalRoute(route);
                aircraft.activateArrivalRoute();
            } else if ("OUT".equals(status.getType())) {
                aircraft.setDepartureRoute(route);
                aircraft.activateDepartureRoute();
            }
            
            // 更新缓存
            activeMovingObjectsCache.put(flightNo, aircraft);
            
            log.debug("成功更新航空器路由缓存: flightNo={}, type={}, codes={}", 
                    flightNo, route.getType(), route.getCodes());
        } else {
            log.debug("缓存中暂无航空器对象，跳过缓存更新: flightNo={}", flightNo);
        }
    }
    
    /**
     * 发布航空器路由更新事件
     */
    private void publishAircraftRouteUpdateEvent(String flightNo, AircraftRoute route, AircraftStatusDTO status) {
        try {
            // 创建路由更新事件
            AircraftRouteUpdateEvent routeUpdateEvent = AircraftRouteUpdateEvent.builder()
                .flightNo(flightNo)
                .routeType(route.getType())
                .routeStatus(route.getStatus())
                .routeCodes(route.getCodes())
                .aircraftStatus(status.getType())
                .routeGeometry(route.getGeometry() != null ? route.getGeometry().toText() : null)
                .timestamp(System.currentTimeMillis())
                .build();
            
            // 发布WebSocket事件
            eventPublisher.publishEvent(routeUpdateEvent);
            
            log.info("发布航空器路由更新事件: 航班号={}, 路由类型={}, 状态={}", 
                    flightNo, route.getType(), status.getType());
            
        } catch (Exception e) {
            log.error("发布航空器路由更新事件失败: flightNo={}", flightNo, e);
        }
    }
    
    /**
     * 定时采集航空器数据
     * - 不进行数据持久化
     */
    @Scheduled(fixedRateString = "${data.collector.interval}")
    public void collectAircraftData() {
        if (collectorDisabled) {
            return;
        }
    
        try {
            List<Aircraft> newAircrafts = dataCollectorDao.collectAircraftData(airportAircraftEndpoint, airportBaseUrl);
            if (newAircrafts.isEmpty()) {
                log.debug("未获取到航空器数据");
                return;
            }

            log.info("采集到 {} 条航空器数据，用于实时处理", newAircrafts.size());
            
            // List<MovingObject> activeMovingObjects = new ArrayList<>(); // 移除此行

            // 航空器数据仅用于实时处理，不存储到数据库
            // 数据处理完成后发布WebSocket事件进行实时推送
            for (Aircraft aircraft : newAircrafts) {
                try {
                    if (aircraft.getCurrentPosition() == null) {
                        log.warn("航空器 {} 位置信息缺失，跳过处理。", aircraft.getObjectId());
                        continue; // 跳过此航空器
                    }
                    Point currentPosition = geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(
                        aircraft.getCurrentPosition().getX(), 
                        aircraft.getCurrentPosition().getY()
                    ));

                    // 数据采集阶段：只采集和缓存位置数据，不进行任何计算
                    MovingObject movingObject = MovingObject.builder()
                        .objectId(aircraft.getObjectId())
                        .objectType(MovingObjectType.AIRCRAFT)
                        .objectName(aircraft.getObjectName())
                        .currentPosition(currentPosition)
                        .currentSpeed(null)    // 不在采集阶段计算速度
                        .currentHeading(null)  // 不在采集阶段计算方向
                        .altitude(aircraft.getAltitude())
                        .build();

                    // 将最新数据更新到缓存（不发送WebSocket消息，统一在周期性检测中发送）
                    activeMovingObjectsCache.put(movingObject.getObjectId(), movingObject);
                    
                    log.debug("处理航空器数据并更新缓存: (航班号: {}, 位置: {}, {}, 速度: {})", 
                             aircraft.getObjectId(),
                             currentPosition.getX(),
                             currentPosition.getY(),
                             movingObject.getCurrentSpeed());
                    
                } catch (Exception e) {
                    log.error("处理航空器数据异常: objectId={}", aircraft.getObjectId(), e); // Changed from flightNo
                }
            }
            
            // 执行路径冲突检测 (临时移除，将在新的定时任务中统一处理)
            // if (!activeMovingObjects.isEmpty()) {
            //     pathConflictDetectionService.detectPathConflicts(activeMovingObjects);
            // }

            // 执行实时违规检测 (临时移除，将在新的定时任务中统一处理)
            // for (MovingObject movingObject : activeMovingObjects) {
            //     VehicleLocation tempVehicleLocation = createTemporaryVehicleLocationForDetection(movingObject);
            //     if (tempVehicleLocation != null) {
            //         List<RuleViolationEvent> violations = realTimeViolationDetector.detectViolations(tempVehicleLocation);
            //         if (!violations.isEmpty()) {
            //             log.warn("检测到航空器违规: objectId={}, 违规数={}", movingObject.getObjectId(), violations.size());
            //             // 如果需要，可以在这里进一步处理这些违规事件，例如持久化或发送告警
            //             // realTimeViolationDetector.processBatchViolationEvents(violations);
            //         }
            //     }
            // }

            log.info("航空器数据处理和事件发布完成，处理数量: {}", newAircrafts.size());
            
        } catch (Exception e) {
            log.error("采集航空器数据异常", e);
        }
    }

    /**
     * 定时采集机场车辆数据
     * 
     * 数据来源：第1章 车辆位置数据接入 (/openApi/getCurrentVehiclePositions)
     * 说明：仅传递目前机场已接入的车辆位置数据（服务车辆、清洁车辆、加油车等）
     * 重构说明：
     * - 机场车辆数据仅用于实时处理，不存储到数据库
     * - 数据采集后直接用于碰撞检测等实时计算
     * - 不进行数据持久化
     */
    @Scheduled(fixedRateString = "${data.collector.interval}")
    @Async  // 异步执行
    public void collectVehicleData() {
        if (collectorDisabled) {
            return;
        }
        
        try {
            List<AirportVehicle> vehicles = dataCollectorDao.collectVehicleData(airportVehicleEndpoint, airportBaseUrl);
            if (vehicles.isEmpty()) {
                log.debug("未获取到机场车辆数据");
                return;
            }
            
            int originalCount = vehicles.size();
            log.info("采集到 {} 条机场车辆数据，开始过滤处理", originalCount);
            
            // 应用车辆位置过滤器
            List<AirportVehicle> filteredVehicles = vehicleLocationFilter.filterVehicles(vehicles);
            int filteredCount = filteredVehicles.size();
            
            if (filteredCount != originalCount) {
                log.info("车辆过滤完成 - 原始数量: {}, 过滤后数量: {}, 被过滤数量: {}", 
                        originalCount, filteredCount, originalCount - filteredCount);
            }
            
            if (filteredVehicles.isEmpty()) {
                log.debug("过滤后没有车辆数据需要处理");
                return;
            }

            // 机场车辆数据仅用于实时处理，不存储到数据库
            // 数据处理完成后发布WebSocket事件进行实时推送
            for (AirportVehicle vehicle : filteredVehicles) {
                try {
                    if (vehicle.getCurrentPosition() == null) {
                        log.warn("机场车辆 {} 位置信息缺失，跳过处理。", vehicle.getObjectId());
                        continue; // 跳过此机场车辆
                    }
                    Point currentPosition = geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(
                        vehicle.getCurrentPosition().getX(), 
                        vehicle.getCurrentPosition().getY()
                    ));

                    // 数据采集阶段：只采集和缓存位置数据，不进行任何计算
                    MovingObject movingObject = MovingObject.builder()
                        .objectId(vehicle.getObjectId())
                        .objectType(MovingObjectType.SPECIAL_VEHICLE)
                        .objectName(vehicle.getObjectName())
                        .currentPosition(currentPosition)
                        .currentSpeed(null)    // 不在采集阶段计算速度
                        .currentHeading(null)  // 不在采集阶段计算方向
                        .altitude(vehicle.getAltitude())
                        .build();

                    // 将最新数据更新到缓存（不发送WebSocket消息，统一在周期性检测中发送）
                    activeMovingObjectsCache.put(movingObject.getObjectId(), movingObject);

                    log.debug("处理机场车辆数据并更新缓存: (车牌号: {}, 位置: {}, {}, 速度: {})", 
                             vehicle.getObjectId(), 
                             currentPosition.getX(),
                             currentPosition.getY(),
                             movingObject.getCurrentSpeed());

                } catch (Exception e) {
                    log.error("处理机场车辆数据异常: objectId={}", vehicle.getObjectId(), e);
                }
            }
            
            // 执行路径冲突检测 (临时移除，将在新的定时任务中统一处理)
            // if (!activeMovingObjects.isEmpty()) {
            //     pathConflictDetectionService.detectPathConflicts(activeMovingObjects);
            // }

            // 执行实时违规检测 (临时移除，将在新的定时任务中统一处理)
            // for (MovingObject movingObject : activeMovingObjects) {
            //     VehicleLocation tempVehicleLocation = createTemporaryVehicleLocationForDetection(movingObject);
            //     if (tempVehicleLocation != null) {
            //         List<RuleViolationEvent> violations = realTimeViolationDetector.detectViolations(tempVehicleLocation);
            //         if (!violations.isEmpty()) {
            //             log.warn("检测到机场车辆违规: objectId={}, 违规数={}", movingObject.getObjectId(), violations.size());
            //             // 如果需要，可以在这里进一步处理这些违规事件，例如持久化或发送告警
            //             // realTimeViolationDetector.processBatchViolationEvents(violations);
            //         }
            //     }
            // }

            log.info("机场车辆数据处理和事件发布完成，处理数量: {}", filteredVehicles.size());

        } catch (Exception e) {
            log.error("采集机场车辆数据异常", e);
        }
    }

    /**
     * 定时采集无人车数据 (外部API)
     * 
     * 数据来源：第2章 无人车位置上报 (/api/VehicleLocationInfo)
     * 说明：仅传递目前无人车平台已接入的无人车位置数据
     * 重构说明：
     * - 无人车数据仅用于实时处理，不存储到数据库
     * - 数据采集后直接用于碰撞检测等实时计算
     * - 不进行数据持久化
     */
    @Scheduled(fixedRateString = "${data.collector.interval}")
    @Async  // 异步执行
    public void collectUnmannedVehicleData() {
        if (collectorDisabled) {
            return;
        }
        
        try {
            List<UnmannedVehicle> unmannedVehicles = dataCollectorDao.getVehicleLocationInfo();
            if (unmannedVehicles.isEmpty()) {
                log.debug("未获取到无人车数据");
                return;
            }
            
            log.info("采集到 {} 条无人车数据", unmannedVehicles.size());

            // 将采集到的无人车数据转换为MovingObject并添加到缓存
            // List<VehicleLocation> unmannedVehicleLocations = new ArrayList<>(); // 移除此行
            
            for (UnmannedVehicle unmannedVehicle : unmannedVehicles) {
                try {
                    if (unmannedVehicle.getCurrentPosition() == null) {
                        log.warn("无人车 {} 位置信息缺失，跳过处理。", unmannedVehicle.getObjectId());
                        continue; // 跳过此无人车
                    }

                    Point currentPosition = geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(
                        unmannedVehicle.getCurrentPosition().getX(), 
                        unmannedVehicle.getCurrentPosition().getY()
                    ));

                    // 数据采集阶段：只采集和缓存位置数据，不进行任何计算
                    MovingObject movingObject = MovingObject.builder()
                        .objectId(unmannedVehicle.getObjectId())
                        .objectType(MovingObjectType.UNMANNED_VEHICLE)
                        .objectName(unmannedVehicle.getObjectName())
                        .currentPosition(currentPosition)
                        .currentSpeed(null)    // 不在采集阶段计算速度
                        .currentHeading(null)  // 不在采集阶段计算方向
                        .altitude(unmannedVehicle.getAltitude())
                        .build();

                    log.debug("在DataCollectorService中，MovingObject的速度: {}", movingObject.getCurrentSpeed());

                    // 注意：电子围栏检测已移至周期性检测方法中，以降低检测频率
                    // 仅在此处更新缓存，实际检测在performPeriodicViolationDetection()中执行

                    // 将最新数据更新到缓存（不保存到数据库，统一在周期性检测中保存）
                    activeMovingObjectsCache.put(movingObject.getObjectId(), movingObject);
                    
                    log.debug("处理无人车数据并更新缓存: (车牌号: {}, 位置: {}, {}, 速度: {})", 
                             unmannedVehicle.getObjectId(), 
                             currentPosition.getX(),
                             currentPosition.getY(),
                             movingObject.getCurrentSpeed());

                } catch (Exception e) {
                    log.error("处理无人车数据异常: objectId={}", unmannedVehicle.getObjectId(), e);
                }
            }

            // 执行路径冲突检测 (临时移除，将在新的定时任务中统一处理)
            // if (!unmannedVehicleLocations.isEmpty()) {
            //     pathConflictDetectionService.detectPathConflicts(unmannedVehicleLocations.stream()
            //             .map(v -> MovingObject.builder()
            //                     .objectId(String.valueOf(v.getVehicleId()))
            //                     .objectType(v.getVehicleType())
            //                     .objectName(v.getVehicleLicense())
            //                     .currentPosition(v.getLocation())
            //                     .currentSpeed(v.getSpeed())
            //                     .currentHeading(v.getHeading())
            //                     .altitude(v.getAltitude())
            //                     .build())
            //             .collect(Collectors.toList()));
            // }

            // 执行实时违规检测 (临时移除，将在新的定时任务中统一处理)
            // if (!unmannedVehicleLocations.isEmpty()) {
            //     realTimeViolationDetector.detectBatchViolations(unmannedVehicleLocations);
            // }
            
            log.info("无人车数据处理和事件发布完成，处理数量: {}", unmannedVehicles.size());

        } catch (Exception e) {
            log.error("采集无人车数据异常", e);
        }
    }

    // 移除周期性处理方法 - 现在由DataProcessingService处理

    /**
     * 统计当前数据采集服务的健康状态和关键指标
     * @return 统计信息字符串
     */
    public String getCollectionStats() {
        long totalAircraft = 0; // 由于不持久化，这里只是示例
        long totalVehicles = 0; // 同上
        // 实际上可以统计已处理的事件数量等
        
        return String.format("DataCollectorService Stats: " +
                             "Total Aircraft Processed: %d, " +
                             "Total Airport Vehicles Processed: %d, " +
                             "Total Unmanned Vehicles Processed: %d", 
                             totalAircraft, totalVehicles, vehicleLocationService.countAllUnmannedVehicles());
    }

    @PreDestroy
    public void shutdown() {
        log.info("DataCollectorService 正在关闭...");
        // 清理资源，如果需要
    }

    // 移除转换方法 - 现在由DataProcessingService处理
    
    // 移除所有处理方法 - 现在由DataProcessingService处理
}
