package com.qaup.collision.rule.service;

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 java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

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

    /**
     * 检查车辆类型是否适用于指定规则
     * @param rule 空间规则
     * @param vehicleType 车辆类型
     * @return 如果车辆类型适用于规则返回true
     */
    boolean isVehicleTypeApplicableToRule(SpatialRule rule, MovingObjectType vehicleType);

    /**
     * 检查车辆类型是否在规则的允许列表中
     * @param rule 空间规则
     * @param vehicleType 车辆类型
     * @return 如果在允许列表中返回true
     */
    boolean isVehicleTypeInAllowedList(SpatialRule rule, MovingObjectType vehicleType);

    /**
     * 检查车辆类型是否在规则的禁止列表中
     * @param rule 空间规则
     * @param vehicleType 车辆类型
     * @return 如果在禁止列表中返回true
     */
    boolean isVehicleTypeInRestrictedList(SpatialRule rule, MovingObjectType vehicleType);

    /**
     * 获取车辆类型的默认权限级别
     * @param vehicleType 车辆类型
     * @return 权限级别（数值越小权限越高）
     */
    int getVehicleTypePermissionLevel(MovingObjectType vehicleType);

    /**
     * 检查车辆类型是否有特殊权限
     * @param vehicleType 车辆类型
     * @return 如果有特殊权限返回true
     */
    boolean hasSpecialPermission(MovingObjectType vehicleType);

    /**
     * 获取车辆类型可以访问的区域类型集合
     * @param vehicleType 车辆类型
     * @return 可访问的区域类型集合
     */
    Set<String> getAccessibleAreaTypes(MovingObjectType vehicleType);

    /**
     * 检查车辆类型是否可以在指定时间访问
     * @param vehicleType 车辆类型
     * @param timestamp 时间戳
     * @return 如果可以访问返回true
     */
    boolean isAccessAllowedAtTime(MovingObjectType vehicleType, LocalDateTime timestamp);

    /**
     * 获取车辆类型的访问限制信息
     * @param vehicleType 车辆类型
     * @return 访问限制信息
     */
    VehicleAccessRestriction getAccessRestriction(MovingObjectType vehicleType);

    /**
     * 验证车辆类型权限配置
     * @param rule 空间规则
     * @return 验证结果
     */
    PermissionValidationResult validateVehicleTypePermission(SpatialRule rule);

    /**
     * 获取车辆类型的优先级
     * @param vehicleType 车辆类型
     * @return 优先级（数值越小优先级越高）
     */
    int getVehicleTypePriority(MovingObjectType vehicleType);

    /**
     * 检查两个车辆类型的权限冲突
     * @param vehicleType1 车辆类型1
     * @param vehicleType2 车辆类型2
     * @return 如果存在权限冲突返回true
     */
    boolean hasPermissionConflict(MovingObjectType vehicleType1, MovingObjectType vehicleType2);

    /**
     * 车辆访问限制信息类
     */
    class VehicleAccessRestriction {
        private final MovingObjectType vehicleType;
        private final Set<RuleCategory> restrictedCategories;
        private final Set<String> restrictedAreaTypes;
        private final boolean requiresSpecialApproval;
        private final int maxSpeed;
        private final String description;

        public VehicleAccessRestriction(MovingObjectType vehicleType, Set<RuleCategory> restrictedCategories,
                                       Set<String> restrictedAreaTypes, boolean requiresSpecialApproval,
                                       int maxSpeed, String description) {
            this.vehicleType = vehicleType;
            this.restrictedCategories = restrictedCategories;
            this.restrictedAreaTypes = restrictedAreaTypes;
            this.requiresSpecialApproval = requiresSpecialApproval;
            this.maxSpeed = maxSpeed;
            this.description = description;
        }

        public MovingObjectType getVehicleType() { return vehicleType; }
        public Set<RuleCategory> getRestrictedCategories() { return restrictedCategories; }
        public Set<String> getRestrictedAreaTypes() { return restrictedAreaTypes; }
        public boolean isRequiresSpecialApproval() { return requiresSpecialApproval; }
        public int getMaxSpeed() { return maxSpeed; }
        public String getDescription() { return description; }

        public boolean isRestrictedForCategory(RuleCategory category) {
            return restrictedCategories.contains(category);
        }

        public boolean isRestrictedForAreaType(String areaType) {
            return restrictedAreaTypes.contains(areaType);
        }

        @Override
        public String toString() {
            return String.format("VehicleAccessRestriction{vehicleType=%s, restrictedCategories=%s, restrictedAreaTypes=%s, requiresSpecialApproval=%s, maxSpeed=%d}",
                               vehicleType, restrictedCategories, restrictedAreaTypes, requiresSpecialApproval, maxSpeed);
        }
    }

    /**
     * 权限验证结果类
     */
    class PermissionValidationResult {
        private final boolean valid;
        private final List<String> errors;
        private final List<String> warnings;
        private final List<String> recommendations;

        public PermissionValidationResult(boolean valid, List<String> errors, List<String> warnings, List<String> recommendations) {
            this.valid = valid;
            this.errors = errors;
            this.warnings = warnings;
            this.recommendations = recommendations;
        }

        public boolean isValid() { return valid; }
        public List<String> getErrors() { return errors; }
        public List<String> getWarnings() { return warnings; }
        public List<String> getRecommendations() { return recommendations; }

        public boolean hasIssues() {
            return !errors.isEmpty() || !warnings.isEmpty();
        }

        @Override
        public String toString() {
            return String.format("PermissionValidationResult{valid=%s, errors=%d, warnings=%d, recommendations=%d}",
                               valid, errors.size(), warnings.size(), recommendations.size());
        }
    }
} 