package com.qaup.collision.common.adapter;

import com.qaup.collision.common.model.spatial.VehicleLocation;
import com.qaup.system.domain.SysVehicleInfo;
import com.qaup.system.domain.SysVehicleType;
import com.qaup.system.service.ISysVehicleInfoService;
import com.qaup.system.service.ISysDriverInfoService;
import com.qaup.system.service.ISysVehicleTypeService;
import org.locationtech.jts.geom.Point;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * QAUP数据适配器
 * 
 * 连接CollisionAvoidanceSystem和QAUP系统的Service层
 * 提供统一的数据访问接口，避免重复编写DAO组件
 * 
 * 主要功能：
 * 1. 车辆信息查询和管理
 * 2. 司机信息查询和管理
 * 3. 车辆类型管理
 * 4. 数据类型转换和适配
 * 
 * @author QuapDataAdapter
 * @date 2025-01-15
 */
@Component
public class QuapDataAdapter {
    
    private static final Logger logger = LoggerFactory.getLogger(QuapDataAdapter.class);
    
    @Autowired
    private ISysVehicleInfoService vehicleInfoService;
    
    @Autowired
    private ISysDriverInfoService driverInfoService;
    
    @Autowired
    private ISysVehicleTypeService vehicleTypeService;

    // ================== 车辆信息管理 ==================
    
    /**
     * 根据车辆ID查询车辆信息
     * 
     * @param vehicleId 车辆ID
     * @return 车辆信息
     */
    public Optional<SysVehicleInfo> findVehicleById(Long vehicleId) {
        try {
            SysVehicleInfo vehicleInfo = vehicleInfoService.selectSysVehicleInfoByVehicleId(vehicleId);
            return Optional.ofNullable(vehicleInfo);
        } catch (Exception e) {
            logger.error("查询车辆信息失败，vehicleId: {}", vehicleId, e);
            return Optional.empty();
        }
    }
    
    /**
     * 根据车牌号查询车辆信息
     * 
     * @param licensePlate 车牌号
     * @return 车辆信息
     */
    public Optional<SysVehicleInfo> findVehicleByLicensePlate(String licensePlate) {
        try {
            SysVehicleInfo queryCondition = new SysVehicleInfo();
            queryCondition.setLicensePlate(licensePlate);
            
            List<SysVehicleInfo> vehicles = vehicleInfoService.selectSysVehicleInfoList(queryCondition);
            if (!vehicles.isEmpty()) {
                return Optional.of(vehicles.get(0));
            }
            return Optional.empty();
        } catch (Exception e) {
            logger.error("根据车牌号查询车辆信息失败，licensePlate: {}", licensePlate, e);
            return Optional.empty();
        }
    }
    
    /**
     * 查询指定类型编码的所有车辆
     * 
     * @param typeCode 车辆类型编码
     * @return 车辆信息列表
     */
    public List<SysVehicleInfo> findVehiclesByTypeCode(String typeCode) {
        try {
            SysVehicleInfo queryCondition = new SysVehicleInfo();
            queryCondition.setTypeCode(typeCode);
            
            return vehicleInfoService.selectSysVehicleInfoList(queryCondition);
        } catch (Exception e) {
            logger.error("根据类型编码查询车辆信息失败，typeCode: {}", typeCode, e);
            return List.of();
        }
    }
    
    /**
     * 查询指定类型的所有车辆（向后兼容方法）
     * 
     * @param typeId 车辆类型ID（已废弃，用于向后兼容）
     * @return 车辆信息列表
     * @deprecated 使用 findVehiclesByTypeCode(String typeCode) 代替
     */
    @Deprecated
    public List<SysVehicleInfo> findVehiclesByType(Long typeId) {
        try {
            // 通过ID查找类型编码，然后使用新方法
            SysVehicleType vehicleType = vehicleTypeService.selectSysVehicleTypeById(typeId);
            if (vehicleType != null && vehicleType.getTypeCode() != null) {
                return findVehiclesByTypeCode(vehicleType.getTypeCode());
            }
            logger.warn("未找到车辆类型，typeId: {}", typeId);
            return List.of();
        } catch (Exception e) {
            logger.error("根据类型ID查询车辆信息失败，typeId: {}", typeId, e);
            return List.of();
        }
    }
    
    /**
     * 查询所有车辆信息
     * 
     * @return 车辆信息列表
     */
    public List<SysVehicleInfo> findAllVehicles() {
        try {
            return vehicleInfoService.selectSysVehicleInfoList(new SysVehicleInfo());
        } catch (Exception e) {
            logger.error("查询所有车辆信息失败", e);
            return List.of();
        }
    }
    
    /**
     * 保存或更新车辆信息
     * 
     * @param vehicleInfo 车辆信息
     * @return 保存结果
     */
    public boolean saveVehicle(SysVehicleInfo vehicleInfo) {
        try {
            if (vehicleInfo.getVehicleId() == null) {
                // 新增
                int result = vehicleInfoService.insertSysVehicleInfo(vehicleInfo);
                return result > 0;
            } else {
                // 更新
                int result = vehicleInfoService.updateSysVehicleInfo(vehicleInfo);
                return result > 0;
            }
        } catch (Exception e) {
            logger.error("保存车辆信息失败", e);
            return false;
        }
    }
    
    // ================== 数据类型转换 ==================
    
    /**
     * 将若依车辆信息转换为CollisionAvoidanceSystem需要的VehicleLocation格式
     * 注意：此方法只转换基础信息，位置和时间信息需要从实时数据中获取
     * 注意：车牌号和车辆类型现在不存储在VehicleLocation中，需要通过vehicleId关联查询
     * 
     * @param sysVehicleInfo 若依车辆信息
     * @param location 实时位置
     * @param timestamp 时间戳
     * @return VehicleLocation对象
     */
    public VehicleLocation convertToVehicleLocation(SysVehicleInfo sysVehicleInfo, 
                                                   Point location, 
                                                   LocalDateTime timestamp) {
        if (sysVehicleInfo == null) {
            return null;
        }
        
        VehicleLocation vehicleLocation = new VehicleLocation();
        vehicleLocation.setVehicleId(sysVehicleInfo.getVehicleId());
        vehicleLocation.setLocation(location);
        vehicleLocation.setTimestamp(timestamp);
        
        return vehicleLocation;
    }

    
    // ================== 查询条件构建辅助方法 ==================
    
    /**
     * 构建车辆查询条件（支持路径编码模式）
     * 
     * @param licensePlate 车牌号（可选）
     * @param typeCode 类型编码（可选）
     * @param owningUnit 所属单位（可选）
     * @return 查询条件对象
     */
    public SysVehicleInfo buildVehicleQueryCondition(String licensePlate, String typeCode, String owningUnit) {
        SysVehicleInfo condition = new SysVehicleInfo();
        condition.setLicensePlate(licensePlate);
        condition.setTypeCode(typeCode);
        condition.setOwningUnit(owningUnit);
        return condition;
    }
    
    /**
     * 批量查询车辆信息
     * 
     * @param vehicleIds 车辆ID列表
     * @return 车辆信息列表
     */
    public List<SysVehicleInfo> findVehiclesByIds(List<Long> vehicleIds) {
        if (vehicleIds == null || vehicleIds.isEmpty()) {
            return List.of();
        }
        
        return vehicleIds.stream()
                .map(this::findVehicleById)
                .filter(Optional::isPresent)
                .map(Optional::get)
                .collect(Collectors.toList());
    }
    
    // ================== 日志和监控方法 ==================
    
    /**
     * 验证适配器初始化状态
     * 
     * @return 初始化是否成功
     */
    public boolean isInitialized() {
        return vehicleInfoService != null && 
               driverInfoService != null && 
               vehicleTypeService != null;
    }
} 