package com.qaup.collision.datacollector.service;

import com.qaup.collision.common.model.MovingObject.MovingObjectType;
import com.qaup.collision.common.model.spatial.VehicleLocation;
import com.qaup.collision.common.service.VehicleLocationService;
import com.qaup.collision.datacollector.model.entity.VehicleCommandEntity;
import com.qaup.collision.datacollector.repository.VehicleCommandRepository;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 车辆数据持久化服务
 * 
 * 实现选择性数据持久化策略：
 * - 无人车位置数据：存储到数据库（用于轨迹回放和日志审计）
 * - 无人车控制指令：存储到数据库（用于日志审计）
 * - 航空器位置数据：仅用于实时处理，不存储
 * - 特种车辆位置数据：仅用于实时处理，不存储
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class VehicleDataPersistenceService {

    private final VehicleLocationService vehicleLocationService;
    private final VehicleCommandRepository vehicleCommandRepository;

    /**
     * 判断是否应该持久化车辆数据
     * 
     * @param vehicleType 车辆类型
     * @return true表示需要持久化，false表示仅实时处理
     */
    public boolean shouldPersistVehicleData(MovingObjectType vehicleType) {
        // 只有无人车数据需要持久化
        return MovingObjectType.UNMANNED_VEHICLE.equals(vehicleType);
    }

    /**
     * 保存无人车位置数据
     * 
     * @param vehicleLocation 车辆位置信息
     * @return 保存后的位置记录
     */
    @Transactional
    public VehicleLocation saveUnmannedVehicleLocation(VehicleLocation vehicleLocation) {
        if (!shouldPersistVehicleData(vehicleLocation.getVehicleType())) {
            log.debug("车辆类型 {} 不需要持久化，跳过存储", vehicleLocation.getVehicleType());
            return vehicleLocation;
        }

        try {
            VehicleLocation savedLocation = vehicleLocationService.saveVehicleLocation(vehicleLocation);
            log.debug("成功保存无人车位置数据: vehicleId={}, location=({}, {})", 
                     savedLocation.getVehicleId(),
                     savedLocation.getLocation().getX(),
                     savedLocation.getLocation().getY());
            
            // 数据保存完成后发布WebSocket位置更新事件
            // 位置数据保存成功，不再在此处发送WebSocket消息
            // WebSocket消息统一由DataCollectorService的周期性检测方法发送
            log.debug("无人车位置数据保存成功: vehicleId={}, 位置=({}, {})", 
                     savedLocation.getVehicleId(),
                     savedLocation.getLocation().getX(),
                     savedLocation.getLocation().getY());
            
            return savedLocation;
        } catch (Exception e) {
            log.error("保存无人车位置数据失败: vehicleId={}", vehicleLocation.getVehicleId(), e);
            throw new RuntimeException("保存无人车位置数据失败", e);
        }
    }

    /**
     * 批量保存无人车位置数据
     * 
     * @param vehicleLocations 车辆位置列表
     * @return 保存后的位置记录列表
     */
    @Transactional
    public List<VehicleLocation> batchSaveUnmannedVehicleLocations(List<VehicleLocation> vehicleLocations) {
        if (vehicleLocations == null || vehicleLocations.isEmpty()) {
            return List.of();
        }

        // 过滤出需要持久化的无人车数据
        List<VehicleLocation> unmannedVehicleLocations = vehicleLocations.stream()
                .filter(location -> shouldPersistVehicleData(location.getVehicleType()))
                .toList();

        if (unmannedVehicleLocations.isEmpty()) {
            log.debug("没有需要持久化的无人车位置数据");
            return List.of();
        }

        try {
            List<VehicleLocation> savedLocations = vehicleLocationService.saveVehicleLocations(unmannedVehicleLocations);
            log.info("批量保存无人车位置数据成功: 数量={}", savedLocations.size());
            return savedLocations;
        } catch (Exception e) {
            log.error("批量保存无人车位置数据失败: 数量={}", unmannedVehicleLocations.size(), e);
            throw new RuntimeException("批量保存无人车位置数据失败", e);
        }
    }

    /**
     * 保存无人车控制指令
     * 
     * @param vehicleCommand 控制指令实体
     * @return 保存后的指令记录
     */
    @Transactional
    public VehicleCommandEntity saveVehicleCommand(VehicleCommandEntity vehicleCommand) {
        try {
            // 设置创建时间
            if (vehicleCommand.getCreatedAt() == null) {
                vehicleCommand.setCreatedAt(LocalDateTime.now());
            }
            if (vehicleCommand.getUpdatedAt() == null) {
                vehicleCommand.setUpdatedAt(LocalDateTime.now());
            }

            VehicleCommandEntity savedCommand = vehicleCommandRepository.save(vehicleCommand);
            log.info("成功保存无人车控制指令: transId={}, vehicleId={}, commandType={}", 
                     savedCommand.getTransId(), 
                     savedCommand.getVehicleId(), 
                     savedCommand.getCommandType());
            return savedCommand;
        } catch (Exception e) {
            log.error("保存无人车控制指令失败: transId={}, vehicleId={}", 
                     vehicleCommand.getTransId(), vehicleCommand.getVehicleId(), e);
            throw new RuntimeException("保存无人车控制指令失败", e);
        }
    }

    /**
     * 批量保存无人车控制指令
     * 
     * @param vehicleCommands 控制指令列表
     * @return 保存后的指令记录列表
     */
    @Transactional
    public List<VehicleCommandEntity> batchSaveVehicleCommands(List<VehicleCommandEntity> vehicleCommands) {
        if (vehicleCommands == null || vehicleCommands.isEmpty()) {
            return List.of();
        }

        try {
            // 设置创建和更新时间
            LocalDateTime now = LocalDateTime.now();
            vehicleCommands.forEach(command -> {
                if (command.getCreatedAt() == null) {
                    command.setCreatedAt(now);
                }
                if (command.getUpdatedAt() == null) {
                    command.setUpdatedAt(now);
                }
            });

            List<VehicleCommandEntity> savedCommands = vehicleCommandRepository.saveAll(vehicleCommands);
            log.info("批量保存无人车控制指令成功: 数量={}", savedCommands.size());
            return savedCommands;
        } catch (Exception e) {
            log.error("批量保存无人车控制指令失败: 数量={}", vehicleCommands.size(), e);
            throw new RuntimeException("批量保存无人车控制指令失败", e);
        }
    }

    /**
     * 获取车辆控制指令历史
     * 
     * @param vehicleId 车辆ID
     * @param limit 限制返回数量
     * @return 控制指令历史列表
     */
    public List<VehicleCommandEntity> getVehicleCommandHistory(Long vehicleId, int limit) {
        try {
            // 将String类型的vehicleId转换为Long类型
            List<VehicleCommandEntity> commands = vehicleCommandRepository
                    .findByVehicleIdOrderByTimestampDesc(vehicleId);
            
            // 限制返回数量
            if (limit > 0 && commands.size() > limit) {
                commands = commands.subList(0, limit);
            }
            
            log.debug("获取车辆控制指令历史: vehicleId={}, 数量={}", vehicleId, commands.size());
            return commands;
        } catch (NumberFormatException e) {
            log.warn("无效的vehicleId格式: {}", vehicleId, e);
            return List.of();
        } catch (Exception e) {
            log.error("获取车辆控制指令历史失败: vehicleId={}", vehicleId, e);
            return List.of();
        }
    }

    /**
     * 获取指定时间范围内的控制指令
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 控制指令列表
     */
    public List<VehicleCommandEntity> getVehicleCommandsByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        try {
            List<VehicleCommandEntity> commands = vehicleCommandRepository
                    .findByTimestampBetween(startTime, endTime);
            
            log.debug("获取时间范围内控制指令: 时间范围=[{}, {}], 数量={}", 
                     startTime, endTime, commands.size());
            return commands;
        } catch (Exception e) {
            log.error("获取时间范围内控制指令失败: 时间范围=[{}, {}]", startTime, endTime, e);
            return List.of();
        }
    }

    /**
     * 清理历史控制指令数据
     * 
     * @param beforeTime 清理此时间之前的数据
     * @return 清理的记录数量
     */
    @Transactional
    public int cleanupHistoricalCommands(LocalDateTime beforeTime) {
        try {
            int deletedCount = vehicleCommandRepository.deleteByTimestampBefore(beforeTime);
            log.info("清理历史控制指令数据完成: 删除记录数={}, 清理时间点={}", deletedCount, beforeTime);
            return deletedCount;
        } catch (Exception e) {
            log.error("清理历史控制指令数据失败: beforeTime={}", beforeTime, e);
            throw new RuntimeException("清理历史控制指令数据失败", e);
        }
    }

    /**
     * 获取数据持久化统计信息
     * 
     * @return 统计信息字符串
     */
    public String getPersistenceStatistics() {
        try {
            StringBuilder stats = new StringBuilder();
            stats.append("数据持久化统计信息:\n");
            
            // 无人车位置数据统计
            long unmannedVehicleCount = vehicleLocationService
                    .getActiveVehiclesByType(MovingObjectType.UNMANNED_VEHICLE, 60).size();
            stats.append("  - 无人车位置记录（最近1小时）: ").append(unmannedVehicleCount).append(" 条\n");
            
            // 控制指令统计
            LocalDateTime oneHourAgo = LocalDateTime.now().minusHours(1);
            LocalDateTime now = LocalDateTime.now();
            long commandCount = getVehicleCommandsByTimeRange(oneHourAgo, now).size();
            stats.append("  - 控制指令记录（最近1小时）: ").append(commandCount).append(" 条\n");
            
            stats.append("  - 持久化策略: 仅无人车数据存储，其他数据仅实时处理\n");
            
            return stats.toString();
        } catch (Exception e) {
            log.error("获取数据持久化统计信息失败", e);
            return "获取统计信息失败: " + e.getMessage();
        }
    }
} 