package com.qaup.collision.datacollector.service;

import com.qaup.collision.common.model.spatial.VehicleLocation;
import com.qaup.collision.datacollector.model.converter.VehicleCommandConverter;
import com.qaup.collision.datacollector.model.dto.VehicleCommand;
import com.qaup.collision.datacollector.model.dto.VehicleStateInfo;
import com.qaup.collision.datacollector.model.entity.VehicleCommandEntity;
import com.qaup.collision.datacollector.repository.VehicleCommandRepository;
import com.qaup.collision.common.model.repository.VehicleLocationRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

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

/**
 * 无人车控制服务类
 * 
 * 负责处理无人车控制指令、位置查询和状态查询的核心业务逻辑
 * 包含与外部无人车系统的通信和数据持久化功能
 * 
 * @author AI Assistant
 * @version 1.0
 * @since 2024-12-19
 */
@Service
@Transactional
public class UnmannedVehicleControlService {

    private static final Logger logger = LoggerFactory.getLogger(UnmannedVehicleControlService.class);

    @Autowired
    private VehicleCommandRepository vehicleCommandRepository;

    @Autowired
    private VehicleLocationRepository vehicleLocationRepository;

    @Autowired
    private VehicleCommandConverter vehicleCommandConverter;

    @Autowired
    private RestTemplate restTemplate;

    // 无人车厂商API配置
    @Value("${data.collector.vehicle-api.base-url}")
    private String vehicleApiBaseUrl;

    @Value("${data.collector.vehicle-api.endpoints.vehicle-command:#{null}}")
    private String vehicleCommandEndpoint;

    @Value("${data.collector.vehicle-api.endpoints.vehicle-location}")
    private String vehicleLocationEndpoint;

    @Value("${data.collector.vehicle-api.endpoints.vehicle-state:#{null}}")
    private String vehicleStateEndpoint;

    /**
     * 处理无人车控制指令
     * 
     * @param vehicleCommand 控制指令对象
     * @return 处理结果描述
     */
    public String processVehicleCommand(VehicleCommand vehicleCommand) {
        logger.info("开始处理无人车控制指令: transId={}, vehicleId={}, commandType={}", 
                   vehicleCommand.getTransId(), vehicleCommand.getVehicleId(), vehicleCommand.getCommandType());

        try {
            // 1. 验证指令参数
            validateVehicleCommand(vehicleCommand);

            // 2. 保存指令到数据库（用于轨迹回放和日志审计）
            VehicleCommandEntity commandEntity = vehicleCommandConverter.toEntity(vehicleCommand);
            VehicleCommandEntity savedCommand = vehicleCommandRepository.save(commandEntity);
            logger.info("控制指令已保存到数据库: id={}, transId={}", 
                       savedCommand.getId(), savedCommand.getTransId());

            // 3. 发送指令到无人车系统（如果配置了外部API）
            String externalResult = sendCommandToVehicleSystem(vehicleCommand);

            // 4. 记录处理结果
            String result = String.format("指令处理成功 - 数据库ID: %d, 外部系统响应: %s", 
                                        savedCommand.getId(), externalResult);
            
            logger.info("无人车控制指令处理完成: transId={}, result={}", 
                       vehicleCommand.getTransId(), result);

            return result;

        } catch (Exception e) {
            logger.error("处理无人车控制指令失败: transId={}, error={}", 
                        vehicleCommand.getTransId(), e.getMessage(), e);
            throw new RuntimeException("控制指令处理失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取无人车位置信息
     * 
     * 注意：只有无人车位置数据存储在数据库中
     * 航空器和特种车辆数据仅用于实时处理，不进行持久化
     * 
     * @param vehicleId 车辆ID，为null时返回所有无人车位置
     * @return 车辆位置信息列表
     */
    @Transactional(readOnly = true)
    public List<VehicleLocation> getVehicleLocations(String vehicleId) {
        logger.info("查询无人车位置信息: vehicleId={}", vehicleId);

        try {
            List<VehicleLocation> locations;
            
            if (vehicleId != null && !vehicleId.trim().isEmpty()) {
                // 查询指定无人车的最新位置
                // 由于数据库中只存储无人车数据，所以不需要额外的类型验证
                try {
                    Long vehicleIdLong = Long.parseLong(vehicleId);
                    Optional<VehicleLocation> latestLocation = vehicleLocationRepository.findLatestByVehicleId(vehicleIdLong);
                    if (latestLocation.isPresent()) {
                        locations = List.of(latestLocation.get());
                        logger.info("查询到指定无人车位置: vehicleId={}", vehicleId);
                    } else {
                        locations = List.of();
                        logger.info("未找到指定无人车: vehicleId={}", vehicleId);
                    }
                } catch (NumberFormatException e) {
                    logger.warn("无效的vehicleId格式: {}", vehicleId);
                    locations = List.of();
                }
            } else {
                // 查询所有无人车的最新位置（最近5分钟内的数据）
                // 由于数据库中只存储无人车数据，直接查询即可
                LocalDateTime since = LocalDateTime.now().minusMinutes(5);
                locations = vehicleLocationRepository.findActiveByVehicleType(
                    "%无人车%", since);
                logger.info("查询到所有无人车位置: count={}", locations.size());
            }

            return locations;

        } catch (Exception e) {
            logger.error("查询无人车位置信息失败: vehicleId={}, error={}", vehicleId, e.getMessage(), e);
            throw new RuntimeException("位置信息查询失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取无人车状态信息
     * 
     * @param vehicleId 车辆ID
     * @return 车辆状态信息
     */
    public VehicleStateInfo getVehicleState(String vehicleId) {
        logger.info("查询无人车状态信息: vehicleId={}", vehicleId);

        try {
            // 如果配置了外部状态查询API，则调用外部系统
            if (vehicleStateEndpoint != null && !vehicleStateEndpoint.trim().isEmpty()) {
                return queryVehicleStateFromExternalSystem(vehicleId);
            } else {
                // 否则基于本地数据构造状态信息
                return buildVehicleStateFromLocalData(vehicleId);
            }

        } catch (Exception e) {
            logger.error("查询无人车状态信息失败: vehicleId={}, error={}", vehicleId, e.getMessage(), e);
            throw new RuntimeException("状态信息查询失败: " + e.getMessage(), e);
        }
    }

    /**
     * 验证控制指令参数
     */
    private void validateVehicleCommand(VehicleCommand command) {
        if (command.getTransId() == null || command.getTransId().trim().isEmpty()) {
            throw new IllegalArgumentException("transId不能为空");
        }
        if (command.getVehicleId() == null) {
            throw new IllegalArgumentException("vehicleId不能为空");
        }
        if (command.getCommandType() == null) {
            throw new IllegalArgumentException("commandType不能为空");
        }
        if (command.getCommandReason() == null) {
            throw new IllegalArgumentException("commandReason不能为空");
        }

        // SIGNAL类型指令必须包含signalState
        if ("SIGNAL".equals(command.getCommandType().name()) && command.getSignalState() == null) {
            throw new IllegalArgumentException("SIGNAL类型指令必须包含signalState");
        }
    }

    /**
     * 发送指令到外部无人车系统
     */
    private String sendCommandToVehicleSystem(VehicleCommand command) {
        if (vehicleCommandEndpoint == null || vehicleCommandEndpoint.trim().isEmpty()) {
            logger.info("未配置外部无人车指令接口，跳过外部系统调用");
            return "未配置外部接口";
        }

        try {
            String url = vehicleApiBaseUrl + vehicleCommandEndpoint;
            
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json");
            
            HttpEntity<VehicleCommand> requestEntity = new HttpEntity<>(command, headers);
            
            ResponseEntity<String> response = restTemplate.exchange(
                url, HttpMethod.POST, requestEntity, String.class);
            
            if (response.getStatusCode().is2xxSuccessful()) {
                logger.info("外部无人车系统调用成功: vehicleId={}, response={}", 
                           command.getVehicleId(), response.getBody());
                return "外部系统调用成功";
            } else {
                logger.warn("外部无人车系统调用失败: vehicleId={}, status={}", 
                           command.getVehicleId(), response.getStatusCode());
                return "外部系统调用失败: " + response.getStatusCode();
            }

        } catch (Exception e) {
            logger.error("调用外部无人车系统异常: vehicleId={}, error={}", 
                        command.getVehicleId(), e.getMessage(), e);
            return "外部系统调用异常: " + e.getMessage();
        }
    }

    /**
     * 从外部系统查询车辆状态
     */
    private VehicleStateInfo queryVehicleStateFromExternalSystem(String vehicleId) {
        try {
            String url = vehicleApiBaseUrl + vehicleStateEndpoint;
            
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json");
            
            // 构造查询请求参数
            VehicleStateQueryRequest queryRequest = new VehicleStateQueryRequest();
            queryRequest.setTransId(UUID.randomUUID().toString());
            queryRequest.setTimestamp(System.currentTimeMillis());
            queryRequest.setVehicleId(vehicleId);
            queryRequest.setSingle(true);
            
            HttpEntity<VehicleStateQueryRequest> requestEntity = new HttpEntity<>(queryRequest, headers);
            
            ResponseEntity<VehicleStateInfo[]> response = restTemplate.exchange(
                url, HttpMethod.POST, requestEntity, VehicleStateInfo[].class);
                
            
            if (response != null && response.getStatusCode().is2xxSuccessful()) {
                VehicleStateInfo[] body = response.getBody();
                if (body != null && body.length > 0) {
                    VehicleStateInfo stateInfo = body[0];
                    logger.info("从外部系统获取车辆状态成功: vehicleId={}", vehicleId);
                    return stateInfo;
                } else {
                    logger.warn("外部系统未返回车辆状态: vehicleId={}", vehicleId);
                    return null;
                }
            } else {
                logger.warn("外部系统调用失败: vehicleId={}, status={}", vehicleId, response != null ? response.getStatusCode() : "无响应");
                return null;
            }

        } catch (Exception e) {
            logger.error("从外部系统查询车辆状态异常: vehicleId={}, error={}", vehicleId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 基于本地数据构造车辆状态信息
     */
    private VehicleStateInfo buildVehicleStateFromLocalData(String vehicleId) {
        // 查询最近的位置信息判断车辆是否在线
        try {
            Long vehicleIdLong = Long.parseLong(vehicleId);
            Optional<VehicleLocation> recentLocation = vehicleLocationRepository.findLatestByVehicleId(vehicleIdLong);
            
            boolean isOnline = recentLocation.isPresent();
            
            // 构造基本状态信息
            VehicleStateInfo stateInfo = new VehicleStateInfo();
            stateInfo.setTransId(UUID.randomUUID().toString());
            stateInfo.setTimestamp(System.currentTimeMillis());
            stateInfo.setVehicleId(vehicleIdLong); // 使用Long类型
            stateInfo.setLoginStatus(isOnline);
            stateInfo.setFaultInfo(List.of()); // 空故障列表
            stateInfo.setActiveSafety(false);
            stateInfo.setRc(false);
            stateInfo.setCommand(0); // 0表示恢复状态
            stateInfo.setAirportInfo(List.of());
            stateInfo.setVehicleMode(isOnline ? 2 : 5); // 2:自动, 5:故障等待
            stateInfo.setGearState(2); // 2:D档
            stateInfo.setChassisReady(isOnline);
            stateInfo.setCollisionStatus(false);
            stateInfo.setClearance(0);
            stateInfo.setTurnSignalStatus(0);
            stateInfo.setPointCloud(List.of());
            
            logger.info("基于本地数据构造车辆状态: vehicleId={}, isOnline={}", vehicleId, isOnline);
            return stateInfo;
        } catch (NumberFormatException e) {
            logger.warn("无效的vehicleId格式: {}", vehicleId);
            return null;
        }
    }

    /**
     * 车辆状态查询请求内部类
     */
    private static class VehicleStateQueryRequest {
        private String transId;
        private long timestamp;
        private String vehicleId;
        private boolean single;

        public String getTransId() { return transId; }
        public void setTransId(String transId) { this.transId = transId; }
        
        public long getTimestamp() { return timestamp; }
        public void setTimestamp(long timestamp) { this.timestamp = timestamp; }
        
        public String getVehicleId() { return vehicleId; }
        public void setVehicleId(String vehicleId) { this.vehicleId = vehicleId; }
        
        public boolean isSingle() { return single; }
        public void setSingle(boolean single) { this.single = single; }
    }
} 