package com.qaup.collision.rule.service.impl;

import com.qaup.collision.common.model.MovingObject.MovingObjectType;
import com.qaup.collision.rule.model.entity.SpatialRule;
import com.qaup.collision.rule.model.enums.RuleCategory;
import com.qaup.collision.rule.service.VehicleTypePermissionService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * 车辆类型权限检查服务实现类
 * 负责验证车辆类型的访问权限和规则适用性
 * 
 * @author AI Assistant
 * @version 1.0
 * @since 2025-01-17
 */
@Service
public class VehicleTypePermissionServiceImpl implements VehicleTypePermissionService {

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

    // 车辆类型权限级别映射（数值越小权限越高）
    private static final Map<MovingObjectType, Integer> PERMISSION_LEVELS = Map.of(
        MovingObjectType.AIRCRAFT, 1,           // 最高权限：航空器
        MovingObjectType.SPECIAL_VEHICLE, 2,    // 特殊权限：特勤车辆
        MovingObjectType.NORMAL_VEHICLE, 3,    // 中等权限：普通车辆
        MovingObjectType.UNMANNED_VEHICLE, 4    // 受控权限：无人车
    );

    // 车辆类型优先级映射（数值越小优先级越高）
    private static final Map<MovingObjectType, Integer> PRIORITY_LEVELS = Map.of(
        MovingObjectType.AIRCRAFT, 1,           // 最高优先级：航空器
        MovingObjectType.SPECIAL_VEHICLE, 2,    // 特殊优先级：特勤车辆
        MovingObjectType.NORMAL_VEHICLE, 3,    // 中等优先级：普通车辆
        MovingObjectType.UNMANNED_VEHICLE, 4    // 低优先级：无人车
    );

    // 特殊权限车辆类型
    private static final Set<MovingObjectType> SPECIAL_PERMISSION_VEHICLES = Set.of(
        MovingObjectType.AIRCRAFT,              // 航空器具有特殊权限
        MovingObjectType.SPECIAL_VEHICLE        // 特勤车辆具有特殊权限
    );

    // 车辆类型可访问区域类型映射
    private static final Map<MovingObjectType, Set<String>> ACCESSIBLE_AREA_TYPES = Map.of(
        MovingObjectType.AIRCRAFT, Set.of("RUNWAY", "TAXIWAY", "APRON", "GATE", "RESTRICTED", "MAINTENANCE", "CARGO", "SAFETY", "SERVICE"),
        MovingObjectType.SPECIAL_VEHICLE, Set.of("TAXIWAY", "APRON", "GATE", "RESTRICTED", "MAINTENANCE", "CARGO", "SAFETY", "SERVICE"),
        MovingObjectType.NORMAL_VEHICLE, Set.of("APRON", "GATE", "MAINTENANCE", "CARGO", "SERVICE", "TAXIWAY"),
        MovingObjectType.UNMANNED_VEHICLE, Set.of("APRON", "MAINTENANCE", "CARGO", "SERVICE")
    );

    @Override
    public boolean isVehicleTypeApplicableToRule(SpatialRule rule, MovingObjectType vehicleType) {
        try {
            // 对于准入控制规则，所有车辆类型都适用（需要进行检查）
            // 具体的访问权限判断由规则执行时的 SpatialRule.isVehicleTypeAllowed() 负责
            if (rule.getCategory() == RuleCategory.ACCESS_CONTROL) {
                return true;
            }
            
            List<MovingObjectType> allowedTypes = rule.getAllowedVehicleTypes();
            
            // 如果规则没有指定车辆类型限制，则对所有车辆适用
            if (allowedTypes == null || allowedTypes.isEmpty()) {
                return true;
            }
            
            // 对于非准入控制规则，检查车辆类型是否在允许列表中
            return allowedTypes.contains(vehicleType);

        } catch (Exception e) {
            logger.error("检查车辆类型规则适用性失败: ruleId={}, vehicleType={}", 
                        rule.getRuleId(), vehicleType, e);
            return false; // 出错时默认不适用
        }
    }

    @Override
    public boolean isVehicleTypeInAllowedList(SpatialRule rule, MovingObjectType vehicleType) {
        try {
            List<MovingObjectType> allowedTypes = rule.getAllowedVehicleTypes();
            
            if (allowedTypes == null || allowedTypes.isEmpty()) {
                return true; // 没有限制则默认允许
            }
            
            return allowedTypes.contains(vehicleType);

        } catch (Exception e) {
            logger.error("检查车辆类型允许列表失败: ruleId={}, vehicleType={}", 
                        rule.getRuleId(), vehicleType, e);
            return false;
        }
    }

    @Override
    public boolean isVehicleTypeInRestrictedList(SpatialRule rule, MovingObjectType vehicleType) {
        try {
            // 当前数据模型中没有明确的禁止列表，使用允许列表的反逻辑
            List<MovingObjectType> allowedTypes = rule.getAllowedVehicleTypes();
            
            if (allowedTypes == null || allowedTypes.isEmpty()) {
                return false; // 没有限制则不在禁止列表中
            }
            
            return !allowedTypes.contains(vehicleType);

        } catch (Exception e) {
            logger.error("检查车辆类型禁止列表失败: ruleId={}, vehicleType={}", 
                        rule.getRuleId(), vehicleType, e);
            return false;
        }
    }

    @Override
    public int getVehicleTypePermissionLevel(MovingObjectType vehicleType) {
        return PERMISSION_LEVELS.getOrDefault(vehicleType, 999); // 默认最低权限级别
    }

    @Override
    public boolean hasSpecialPermission(MovingObjectType vehicleType) {
        return SPECIAL_PERMISSION_VEHICLES.contains(vehicleType);
    }

    @Override
    public Set<String> getAccessibleAreaTypes(MovingObjectType vehicleType) {
        return ACCESSIBLE_AREA_TYPES.getOrDefault(vehicleType, new HashSet<>());
    }

    @Override
    public boolean isAccessAllowedAtTime(MovingObjectType vehicleType, LocalDateTime timestamp) {
        try {
            // 检查是否在工作时间内
            LocalTime currentTime = timestamp.toLocalTime();
            
            switch (vehicleType) {
                case AIRCRAFT:
                    // 航空器24小时可访问
                    return true;
                    
                case SPECIAL_VEHICLE:
                    // 特勤车辆24小时可访问（紧急需要）
                    return true;
                    
                case NORMAL_VEHICLE:
                    // 普通车辆一般在05:00-23:00可访问
                    return !currentTime.isBefore(LocalTime.of(5, 0)) && 
                           !currentTime.isAfter(LocalTime.of(23, 0));
                    
                case UNMANNED_VEHICLE:
                    // 无人车一般在06:00-22:00可访问
                    return !currentTime.isBefore(LocalTime.of(6, 0)) && 
                           !currentTime.isAfter(LocalTime.of(22, 0));
                    
                default:
                    return true; // 默认允许
            }

        } catch (Exception e) {
            logger.error("检查时间访问权限失败: vehicleType={}, timestamp={}", vehicleType, timestamp, e);
            return true; // 出错时默认允许
        }
    }

    @Override
    public VehicleAccessRestriction getAccessRestriction(MovingObjectType vehicleType) {
        try {
            switch (vehicleType) {
                case AIRCRAFT:
                    return new VehicleAccessRestriction(
                        vehicleType,
                        Set.of(), // 无限制类别
                        Set.of(), // 无限制区域
                        false,    // 不需要特殊批准
                        300,      // 最大速度300km/h
                        "航空器具有最高权限，可访问所有区域"
                    );
                    
                case SPECIAL_VEHICLE:
                    return new VehicleAccessRestriction(
                        vehicleType,
                        Set.of(), // 无限制类别（紧急情况下）
                        Set.of("RUNWAY"), // 仅限制跑道（安全考虑）
                        false,    // 不需要特殊批准（已有特殊权限）
                        120,      // 最大速度120km/h
                        "特勤车辆具有特殊权限，可紧急通行大部分区域"
                    );
                    
                case NORMAL_VEHICLE:
                    return new VehicleAccessRestriction(
                        vehicleType,
                        Set.of(RuleCategory.PRIORITY_CONTROL), // 限制优先级控制
                        Set.of("RUNWAY", "RESTRICTED"),         // 限制跑道和受限区域
                        true,     // 需要特殊批准访问某些区域
                        80,       // 最大速度80km/h
                        "普通车辆有限制访问，不能进入跑道和受限区域"
                    );
                    
                case UNMANNED_VEHICLE:
                    return new VehicleAccessRestriction(
                        vehicleType,
                        Set.of(RuleCategory.PRIORITY_CONTROL, RuleCategory.SAFETY_ZONE), // 限制优先级和安全区域
                        Set.of("RUNWAY", "TAXIWAY", "RESTRICTED", "GATE"),               // 限制多个区域
                        true,     // 需要特殊批准
                        30,       // 最大速度30km/h
                        "无人车受严格限制，只能在指定区域活动"
                    );
                    
                default:
                    return new VehicleAccessRestriction(
                        vehicleType,
                        Set.of(RuleCategory.values()), // 全部限制
                        Set.of("ALL"),                  // 全部区域限制
                        true,     // 需要特殊批准
                        10,       // 最大速度10km/h
                        "未知车辆类型，严格限制访问"
                    );
            }

        } catch (Exception e) {
            logger.error("获取车辆访问限制失败: vehicleType={}", vehicleType, e);
            return new VehicleAccessRestriction(vehicleType, Set.of(), Set.of(), false, 50, "默认限制");
        }
    }

    @Override
    public PermissionValidationResult validateVehicleTypePermission(SpatialRule rule) {
        List<String> errors = new ArrayList<>();
        List<String> warnings = new ArrayList<>();
        List<String> recommendations = new ArrayList<>();

        try {
            List<MovingObjectType> allowedTypes = rule.getAllowedVehicleTypes();
            
            // 验证车辆类型列表
            if (allowedTypes != null && !allowedTypes.isEmpty()) {
                // 检查是否包含无效的车辆类型组合
                if (allowedTypes.contains(MovingObjectType.AIRCRAFT) && 
                    allowedTypes.contains(MovingObjectType.UNMANNED_VEHICLE)) {
                    warnings.add("航空器和无人车同时允许访问可能存在安全风险");
                }
                
                // 检查规则类别与车辆类型的兼容性
                if (rule.getCategory() == RuleCategory.ACCESS_CONTROL && 
                    allowedTypes.contains(MovingObjectType.AIRCRAFT)) {
                    recommendations.add("建议为航空器单独设置访问控制规则");
                }
                
                // 检查是否遗漏了必要的车辆类型
                if (rule.getCategory() == RuleCategory.SPEED_LIMIT && 
                    !allowedTypes.contains(MovingObjectType.UNMANNED_VEHICLE)) {
                    recommendations.add("建议限速规则包含无人车类型");
                }
            } else {
                warnings.add("规则未指定车辆类型限制，将对所有车辆生效");
            }

        } catch (Exception e) {
            errors.add("验证车辆类型权限配置时发生异常: " + e.getMessage());
        }

        return new PermissionValidationResult(errors.isEmpty(), errors, warnings, recommendations);
    }

    @Override
    public int getVehicleTypePriority(MovingObjectType vehicleType) {
        return PRIORITY_LEVELS.getOrDefault(vehicleType, 999); // 默认最低优先级
    }

    @Override
    public boolean hasPermissionConflict(MovingObjectType vehicleType1, MovingObjectType vehicleType2) {
        try {
            // 检查权限级别差异
            int level1 = getVehicleTypePermissionLevel(vehicleType1);
            int level2 = getVehicleTypePermissionLevel(vehicleType2);
            
            // 权限级别差异过大可能存在冲突
            if (Math.abs(level1 - level2) >= 2) {
                return true;
            }
            
            // 检查特殊冲突组合
            if ((vehicleType1 == MovingObjectType.AIRCRAFT && vehicleType2 == MovingObjectType.UNMANNED_VEHICLE) ||
                (vehicleType1 == MovingObjectType.UNMANNED_VEHICLE && vehicleType2 == MovingObjectType.AIRCRAFT)) {
                return true; // 航空器与无人车存在明显冲突
            }
            
            return false;

        } catch (Exception e) {
            logger.error("检查权限冲突失败: vehicleType1={}, vehicleType2={}", vehicleType1, vehicleType2, e);
            return false;
        }
    }
} 