package com.qaup.collision.datacollector.service;

import com.qaup.collision.common.model.AircraftRoute;
import com.qaup.collision.pathconflict.model.entity.TransportRoute;
import com.qaup.collision.pathconflict.repository.TransportRouteRepository;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.LineString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.qaup.collision.pathconflict.model.entity.ObjectRouteAssignment;
import com.qaup.collision.pathconflict.repository.ObjectRouteAssignmentRepository;
import java.time.LocalDateTime;
import java.util.Optional;

/**
 * 路由持久化服务
 * 负责将解析后的航空器路由数据保存到transport_routes表
 */
@Slf4j
@Service
public class RoutePersistenceService {

    @Autowired
    private TransportRouteRepository transportRouteRepository;
    
    @Autowired
    private ObjectRouteAssignmentRepository objectRouteAssignmentRepository;

    /**
     * 保存或更新航空器路由
     * 
     * @param flightNo 航班号
     * @param aircraftRoute 航空器路由对象
     * @return 是否保存成功
     */
    @Transactional
    public boolean saveAircraftRoute(String flightNo, AircraftRoute aircraftRoute) {
        if (aircraftRoute == null || aircraftRoute.getGeometry() == null) {
            log.warn("航空器路由数据为空，无法保存: flightNo={}", flightNo);
            return false;
        }

        try {
            // 生成路由名称
            String routeName = generateRouteName(flightNo, aircraftRoute);
            
            // 查找是否已存在相同的路由
            Optional<TransportRoute> existingRoute = transportRouteRepository
                .findByRouteNameAndRouteType(routeName, TransportRoute.RouteType.AIRCRAFT);

            TransportRoute transportRoute;
            if (existingRoute.isPresent()) {
                // 更新现有路由
                transportRoute = existingRoute.get();
                transportRoute.setRouteGeometry(aircraftRoute.getGeometry());
                transportRoute.setDescription(buildRouteDescription(aircraftRoute));
                transportRoute.setUpdatedAt(LocalDateTime.now());
                transportRoute.setUpdatedBy("DataCollectorService");
                log.info("更新现有航空器路由: routeName={}, geometry={}个坐标点", 
                        routeName, aircraftRoute.getGeometry().getNumPoints());
            } else {
                // 创建新路由
                transportRoute = TransportRoute.builder()
                    .routeName(routeName)
                    .routeType(TransportRoute.RouteType.AIRCRAFT)
                    .description(buildRouteDescription(aircraftRoute))
                    .routeGeometry(aircraftRoute.getGeometry())
                    .maxSpeedKph(50.0) // 航空器滑行最大速度50km/h
                    .typicalSpeedKph(30.0) // 典型滑行速度30km/h
                    .status(TransportRoute.RouteStatus.ACTIVE)
                    .isBidirectional(false) // 航空器路由通常是单向的
                    .createdBy("DataCollectorService")
                    .updatedBy("DataCollectorService")
                    .createdAt(LocalDateTime.now())
                    .updatedAt(LocalDateTime.now())
                    .build();
                log.info("创建新航空器路由: routeName={}, geometry={}个坐标点", 
                        routeName, aircraftRoute.getGeometry().getNumPoints());
            }

            // 保存到数据库
            TransportRoute saved = transportRouteRepository.save(transportRoute);
            log.info("成功保存航空器路由到数据库: id={}, routeName={}", saved.getId(), saved.getRouteName());
            
            // 保存路由分配记录
            saveRouteAssignment(flightNo, saved.getId(), aircraftRoute.getType());
            
            return true;

        } catch (Exception e) {
            log.error("保存航空器路由失败: flightNo={}", flightNo, e);
            return false;
        }
    }

    /**
     * 生成路由名称
     * 格式: FLIGHT_CA3456_IN 或 FLIGHT_CA3456_OUT
     */
    private String generateRouteName(String flightNo, AircraftRoute aircraftRoute) {
        String routeType = aircraftRoute.getType() != null ? aircraftRoute.getType().toUpperCase() : "UNKNOWN";
        return String.format("FLIGHT_%s_%s", flightNo, routeType);
    }

    /**
     * 构建路由描述
     */
    private String buildRouteDescription(AircraftRoute aircraftRoute) {
        StringBuilder description = new StringBuilder();
        
        // 基本信息
        description.append("航空器路由 - ");
        description.append("类型: ").append(aircraftRoute.getType()).append(", ");
        description.append("状态: ").append(aircraftRoute.getStatus()).append(", ");
        
        // 路径编码
        if (aircraftRoute.getCodes() != null && !aircraftRoute.getCodes().isEmpty()) {
            description.append("路径: ").append(aircraftRoute.getCodes()).append(", ");
        }
        
        // 路径段信息
        if (aircraftRoute.getRouteSegments() != null && !aircraftRoute.getRouteSegments().isEmpty()) {
            description.append("包含 ").append(aircraftRoute.getRouteSegments().size()).append(" 个路径段, ");
        }
        
        // 几何信息
        if (aircraftRoute.getGeometry() != null) {
            description.append("总坐标点: ").append(aircraftRoute.getGeometry().getNumPoints());
        }

        return description.toString();
    }

    /**
     * 删除航空器路由
     */
    @Transactional
    public boolean deleteAircraftRoute(String flightNo, String routeType) {
        try {
            String routeName = String.format("FLIGHT_%s_%s", flightNo, routeType.toUpperCase());
            Optional<TransportRoute> existingRoute = transportRouteRepository
                .findByRouteNameAndRouteType(routeName, TransportRoute.RouteType.AIRCRAFT);

            if (existingRoute.isPresent()) {
                transportRouteRepository.delete(existingRoute.get());
                log.info("成功删除航空器路由: routeName={}", routeName);
                return true;
            } else {
                log.warn("未找到要删除的航空器路由: routeName={}", routeName);
                return false;
            }
        } catch (Exception e) {
            log.error("删除航空器路由失败: flightNo={}, routeType={}", flightNo, routeType, e);
            return false;
        }
    }

    /**
     * 获取航空器路由
     */
    public Optional<TransportRoute> getAircraftRoute(String flightNo, String routeType) {
        try {
            String routeName = String.format("FLIGHT_%s_%s", flightNo, routeType.toUpperCase());
            return transportRouteRepository.findByRouteNameAndRouteType(routeName, TransportRoute.RouteType.AIRCRAFT);
        } catch (Exception e) {
            log.error("获取航空器路由失败: flightNo={}, routeType={}", flightNo, routeType, e);
            return Optional.empty();
        }
    }

    /**
     * 保存路由分配记录（避免重复记录）
     * 
     * @param objectName 对象名称（航班号或车牌号）
     * @param routeId 路由ID
     * @param routeType 路由类型（IN/OUT）
     */
    @Transactional
    private void saveRouteAssignment(String objectName, Long routeId, String routeType) {
        try {
            // 查找当前路由信息
            Optional<TransportRoute> currentRoute = transportRouteRepository.findById(routeId);
            if (!currentRoute.isPresent()) {
                log.warn("路由ID不存在，无法保存分配记录: routeId={}", routeId);
                return;
            }
            
            String currentRouteName = currentRoute.get().getRouteName();
            
            // 检查是否已存在相同航班号的最新分配记录
            Optional<ObjectRouteAssignment> existingAssignment = objectRouteAssignmentRepository
                .findFirstByObjectNameAndObjectTypeOrderByAssignedAtDesc(
                    objectName, 
                    ObjectRouteAssignment.ObjectType.AIRCRAFT
                );
            
            // 如果存在记录，检查是否为相同路由
            if (existingAssignment.isPresent()) {
                Long existingRouteId = existingAssignment.get().getAssignedRouteId();
                
                // 如果路由ID完全相同，则跳过重复记录
                if (existingRouteId.equals(routeId)) {
                    log.info("路由分配未变更，跳过重复记录: objectName={}, routeType={}, routeId={}", 
                            objectName, routeType, routeId);
                    return;
                }
                
                // 进一步检查路由名称是否相同（防止相同路由不同ID的情况）
                Optional<TransportRoute> existingRoute = transportRouteRepository.findById(existingRouteId);
                if (existingRoute.isPresent() && 
                    existingRoute.get().getRouteName().equals(currentRouteName)) {
                    log.info("路由名称相同，跳过重复记录: objectName={}, routeName={}, existingRouteId={}, currentRouteId={}", 
                            objectName, currentRouteName, existingRouteId, routeId);
                    return;
                }
            }
            
            // 创建新的路由分配记录
            ObjectRouteAssignment assignment = ObjectRouteAssignment.builder()
                .objectType(ObjectRouteAssignment.ObjectType.AIRCRAFT)
                .objectName(objectName)
                .assignedRouteId(routeId)
                .assignedAt(LocalDateTime.now())
                .build();
            
            ObjectRouteAssignment saved = objectRouteAssignmentRepository.save(assignment);
            log.info("成功保存路由分配记录: id={}, objectName={}, routeType={}, routeId={}, routeName={}", 
                    saved.getId(), objectName, routeType, routeId, currentRouteName);
                    
        } catch (Exception e) {
            log.error("保存路由分配记录失败: objectName={}, routeType={}, routeId={}", 
                    objectName, routeType, routeId, e);
        }
    }
    
    /**
     * 验证LineString的有效性
     */
    private boolean isValidLineString(LineString lineString) {
        return lineString != null && lineString.isValid() && lineString.getNumPoints() >= 2;
    }
}