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 com.qaup.collision.rule.model.enums.RuleStatus;
import com.qaup.collision.rule.model.enums.SpatialObjectType;

import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;

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

/**
 * 空间规则服务接口
 * 统一规则引擎的核心服务接口，提供规则管理、查询和执行的完整功能
 * 
 * @author AI Assistant
 * @version 1.0
 * @since 2025-01-17
 */
public interface SpatialRuleService {

    // ========== 规则基础管理 ==========

    /**
     * 创建新的空间规则
     * @param rule 规则对象
     * @return 创建成功的规则对象
     * @throws IllegalArgumentException 当规则参数无效时
     */
    SpatialRule createRule(SpatialRule rule);

    /**
     * 批量创建空间规则
     * @param rules 规则列表
     * @return 创建成功的规则列表
     * @throws IllegalArgumentException 当任何规则参数无效时
     */
    List<SpatialRule> createRules(List<SpatialRule> rules);

    /**
     * 更新空间规则
     * @param ruleId 规则ID
     * @param rule 更新的规则对象
     * @return 更新后的规则对象
     * @throws IllegalArgumentException 当规则不存在或参数无效时
     */
    SpatialRule updateRule(String ruleId, SpatialRule rule);

    /**
     * 根据ID删除规则
     * @param ruleId 规则ID
     * @return 如果删除成功返回true
     */
    boolean deleteRule(String ruleId);

    /**
     * 批量删除规则
     * @param ruleIds 规则ID列表
     * @return 成功删除的规则数量
     */
    int deleteRules(List<String> ruleIds);

    /**
     * 根据ID查询规则
     * @param ruleId 规则ID
     * @return 规则对象，如果不存在返回空
     */
    Optional<SpatialRule> findRuleById(String ruleId);

    /**
     * 查询所有规则
     * @return 所有规则列表
     */
    List<SpatialRule> findAllRules();

    // ========== 规则状态管理 ==========

    /**
     * 启用规则
     * @param ruleId 规则ID
     * @return 如果操作成功返回true
     */
    boolean enableRule(String ruleId);

    /**
     * 禁用规则
     * @param ruleId 规则ID
     * @return 如果操作成功返回true
     */
    boolean disableRule(String ruleId);

    /**
     * 批量启用规则
     * @param ruleIds 规则ID列表
     * @return 成功启用的规则数量
     */
    int enableRules(List<String> ruleIds);

    /**
     * 批量禁用规则
     * @param ruleIds 规则ID列表
     * @return 成功禁用的规则数量
     */
    int disableRules(List<String> ruleIds);

    /**
     * 设置规则的有效期
     * @param ruleId 规则ID
     * @param validFrom 有效开始时间
     * @param validTo 有效结束时间
     * @return 如果操作成功返回true
     */
    boolean setRuleValidPeriod(String ruleId, LocalDateTime validFrom, LocalDateTime validTo);

    // ========== 规则查询和筛选 ==========

    /**
     * 根据规则分类查询规则
     * @param category 规则分类
     * @return 指定分类的规则列表
     */
    List<SpatialRule> findRulesByCategory(RuleCategory category);

    /**
     * 根据规则状态查询规则
     * @param status 规则状态
     * @return 指定状态的规则列表
     */
    List<SpatialRule> findRulesByStatus(RuleStatus status);

    /**
     * 根据空间对象类型查询规则
     * @param objectType 空间对象类型
     * @return 指定对象类型的规则列表
     */
    List<SpatialRule> findRulesBySpatialObjectType(SpatialObjectType objectType);

    /**
     * 根据关联对象ID查询规则
     * @param objectId 关联对象ID（如区域ID、道路ID等）
     * @return 关联到指定对象的规则列表
     */
    List<SpatialRule> findRulesByObjectId(String objectId);

    /**
     * 根据优先级范围查询规则
     * @param minPriority 最小优先级
     * @param maxPriority 最大优先级
     * @return 指定优先级范围内的规则列表
     */
    List<SpatialRule> findRulesByPriorityRange(Integer minPriority, Integer maxPriority);

    /**
     * 查询当前有效的规则
     * @return 当前时间有效的规则列表
     */
    List<SpatialRule> findActiveRules();

    /**
     * 查询即将过期的规则
     * @param beforeTime 过期时间阈值
     * @return 在指定时间前过期的规则列表
     */
    List<SpatialRule> findExpiringRules(LocalDateTime beforeTime);

    // ========== 空间查询功能 ==========

    /**
     * 查询适用于指定位置的规则
     * @param location 位置点
     * @param vehicleType 车辆类型
     * @return 适用的规则列表，按优先级排序
     */
    List<SpatialRule> findApplicableRules(Point location, MovingObjectType vehicleType);

    /**
     * 查询适用于指定位置和时间的规则
     * @param location 位置点
     * @param vehicleType 车辆类型
     * @param timestamp 时间戳
     * @return 适用的规则列表，按优先级排序
     */
    List<SpatialRule> findApplicableRules(Point location, MovingObjectType vehicleType, LocalDateTime timestamp);

    /**
     * 查询与指定几何形状相交的规则
     * @param geometry 几何形状
     * @return 相交的规则列表
     */
    List<SpatialRule> findRulesIntersecting(Geometry geometry);

    /**
     * 查询包含指定位置的规则
     * @param location 位置点
     * @return 包含该位置的规则列表
     */
    List<SpatialRule> findRulesContaining(Point location);

    /**
     * 查询指定半径范围内的规则
     * @param center 中心点
     * @param radiusMeters 半径（米）
     * @return 范围内的规则列表
     */
    List<SpatialRule> findRulesWithinRadius(Point center, double radiusMeters);

    /**
     * 查询适用于指定位置和时间的规则
     * @param location 位置点
     * @param timestamp 时间戳
     * @return 适用的规则列表
     */
    List<SpatialRule> findRulesByLocation(Point location, LocalDateTime timestamp);

    /**
     * 检查位置是否在指定区域内
     * @param location 位置点
     * @param areaId 区域ID
     * @return 如果在区域内返回true
     */
    boolean isLocationInArea(Point location, String areaId);

    /**
     * 检查位置是否在指定道路上
     * @param location 位置点
     * @param roadId 道路ID
     * @return 如果在道路上返回true
     */
    boolean isLocationOnRoad(Point location, String roadId);

    /**
     * 检查位置是否在指定路口
     * @param location 位置点
     * @param intersectionId 路口ID
     * @return 如果在路口返回true
     */
    boolean isLocationAtIntersection(Point location, String intersectionId);

    /**
     * 检查位置是否在自定义几何形状内
     * @param location 位置点
     * @param geometry 自定义几何形状
     * @return 如果在几何形状内返回true
     */
    boolean isLocationInCustomGeometry(Point location, Geometry geometry);

    // ========== 规则执行和检测 ==========

    /**
     * 检查车辆是否违反指定规则
     * @param ruleId 规则ID
     * @param vehicleId 车辆ID
     * @param vehicleType 车辆类型
     * @param location 车辆位置
     * @param vehicleState 车辆状态（速度、高度、重量等）
     * @return 如果违规返回true
     */
    boolean checkRuleViolation(String ruleId, String vehicleId, MovingObjectType vehicleType, 
                               Point location, Map<String, Object> vehicleState);

    /**
     * 检查车辆在指定位置是否违反任何规则
     * @param vehicleId 车辆ID
     * @param vehicleType 车辆类型
     * @param location 车辆位置
     * @param vehicleState 车辆状态
     * @return 违反的规则列表
     */
    List<SpatialRule> checkAllRuleViolations(String vehicleId, MovingObjectType vehicleType, 
                                             Point location, Map<String, Object> vehicleState);

    /**
     * 检查车辆在指定位置和时间是否违反任何规则
     * @param vehicleId 车辆ID
     * @param vehicleType 车辆类型
     * @param location 车辆位置
     * @param vehicleState 车辆状态
     * @param timestamp 时间戳
     * @return 违反的规则列表
     */
    List<SpatialRule> checkAllRuleViolations(String vehicleId, MovingObjectType vehicleType, 
                                             Point location, Map<String, Object> vehicleState, 
                                             LocalDateTime timestamp);

    /**
     * 执行单个规则检查
     * @param rule 规则对象
     * @param vehicleId 车辆ID
     * @param vehicleType 车辆类型
     * @param location 车辆位置
     * @param vehicleState 车辆状态
     * @param timestamp 时间戳
     * @return 规则执行结果
     */
    RuleExecutionContext executeRule(SpatialRule rule, String vehicleId, MovingObjectType vehicleType, 
                                     Point location, Map<String, Object> vehicleState, LocalDateTime timestamp);

    // ========== 规则配置验证 ==========

    /**
     * 验证规则配置的有效性
     * @param rule 规则对象
     * @return 验证结果，包含错误信息
     */
    RuleValidationResult validateRule(SpatialRule rule);

    /**
     * 批量验证规则配置
     * @param rules 规则列表
     * @return 验证结果列表
     */
    List<RuleValidationResult> validateRules(List<SpatialRule> rules);

    /**
     * 检查规则冲突
     * @param rule 待检查的规则
     * @return 冲突的规则列表
     */
    List<SpatialRule> findConflictingRules(SpatialRule rule);

    /**
     * 检查规则几何形状的有效性
     * @param geometry 几何形状
     * @return 如果几何形状有效返回true
     */
    boolean isGeometryValid(Geometry geometry);

    // ========== 统计和分析 ==========

    /**
     * 统计各类型规则的数量
     * @return 规则类型统计信息
     */
    Map<RuleCategory, Long> getRuleCountByCategory();

    /**
     * 统计各状态规则的数量
     * @return 规则状态统计信息
     */
    Map<RuleStatus, Long> getRuleCountByStatus();

    /**
     * 获取规则执行统计信息
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 执行统计信息
     */
    RuleExecutionStatistics getRuleExecutionStatistics(LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 获取最活跃的规则列表
     * @param limit 返回数量限制
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 最活跃的规则列表
     */
    List<SpatialRule> getMostActiveRules(int limit, LocalDateTime startTime, LocalDateTime endTime);

    // ========== 规则导入导出 ==========

    /**
     * 从配置文件导入规则
     * @param configData 配置数据
     * @return 导入的规则数量
     */
    int importRulesFromConfig(String configData);

    /**
     * 导出规则配置
     * @param ruleIds 要导出的规则ID列表，null表示导出所有规则
     * @return 配置数据字符串
     */
    String exportRulesToConfig(List<String> ruleIds);

    /**
     * 复制规则
     * @param sourceRuleId 源规则ID
     * @param targetRuleId 目标规则ID
     * @return 复制的规则对象
     */
    SpatialRule cloneRule(String sourceRuleId, String targetRuleId);

    // ========== 缓存管理 ==========

    /**
     * 刷新规则缓存
     */
    void refreshRuleCache();

    /**
     * 清空规则缓存
     */
    void clearRuleCache();

    /**
     * 预热规则缓存
     * @param location 预热的位置中心点
     * @param radiusMeters 预热半径
     */
    void warmupRuleCache(Point location, double radiusMeters);

    /**
     * 查找区域的活跃规则
     * @param areaCode 区域编码
     * @param category 规则分类
     * @return 适用的规则列表
     */
    List<SpatialRule> findActiveRulesForArea(String areaCode, RuleCategory category);

    // ========== 规则执行上下文 ==========

    /**
     * 规则执行上下文类
     * 封装规则执行的完整结果信息
     */
    class RuleExecutionContext {
        private final SpatialRule rule;
        private final String vehicleId;
        private final MovingObjectType vehicleType;
        private final Point location;
        private final Map<String, Object> vehicleState;
        private final LocalDateTime timestamp;
        private final boolean applicable;
        private final boolean violated;
        private final String description;
        private final Map<String, Object> executionDetails;

        public RuleExecutionContext(SpatialRule rule, String vehicleId, MovingObjectType vehicleType,
                                    Point location, Map<String, Object> vehicleState, LocalDateTime timestamp,
                                    boolean applicable, boolean violated, String description,
                                    Map<String, Object> executionDetails) {
            this.rule = rule;
            this.vehicleId = vehicleId;
            this.vehicleType = vehicleType;
            this.location = location;
            this.vehicleState = vehicleState;
            this.timestamp = timestamp;
            this.applicable = applicable;
            this.violated = violated;
            this.description = description;
            this.executionDetails = executionDetails;
        }

        // Getters
        public SpatialRule getRule() { return rule; }
        public String getVehicleId() { return vehicleId; }
        public MovingObjectType getVehicleType() { return vehicleType; }
        public Point getLocation() { return location; }
        public Map<String, Object> getVehicleState() { return vehicleState; }
        public LocalDateTime getTimestamp() { return timestamp; }
        public boolean isApplicable() { return applicable; }
        public boolean isViolated() { return violated; }
        public String getDescription() { return description; }
        public Map<String, Object> getExecutionDetails() { return executionDetails; }
    }

    // ========== 规则验证结果 ==========

    /**
     * 规则验证结果类
     * 封装规则配置验证的结果信息
     */
    class RuleValidationResult {
        private final boolean valid;
        private final List<String> errors;
        private final List<String> warnings;

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

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

    // ========== 规则执行统计 ==========

    /**
     * 规则执行统计信息类
     * 封装规则执行的统计数据
     */
    class RuleExecutionStatistics {
        private final long totalExecutions;
        private final long totalViolations;
        private final double violationRate;
        private final Map<String, Long> violationsByRule;
        private final Map<RuleCategory, Long> violationsByCategory;

        public RuleExecutionStatistics(long totalExecutions, long totalViolations, 
                                       double violationRate, Map<String, Long> violationsByRule,
                                       Map<RuleCategory, Long> violationsByCategory) {
            this.totalExecutions = totalExecutions;
            this.totalViolations = totalViolations;
            this.violationRate = violationRate;
            this.violationsByRule = violationsByRule;
            this.violationsByCategory = violationsByCategory;
        }

        // Getters
        public long getTotalExecutions() { return totalExecutions; }
        public long getTotalViolations() { return totalViolations; }
        public double getViolationRate() { return violationRate; }
        public Map<String, Long> getViolationsByRule() { return violationsByRule; }
        public Map<RuleCategory, Long> getViolationsByCategory() { return violationsByCategory; }
    }
} 