package com.qaup.collision.rule.service;

import com.qaup.collision.rule.model.entity.SpatialRule;
import com.fasterxml.jackson.databind.JsonNode;

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

/**
 * 时间窗口匹配服务接口
 * 提供复杂的时间模式匹配和验证功能
 * 
 * @author AI Assistant
 * @version 1.0
 * @since 2025-01-17
 */
public interface TimeWindowMatchingService {

    /**
     * 检查规则在指定时间是否有效
     * @param rule 空间规则
     * @param timestamp 检查时间
     * @return 如果规则在指定时间有效返回true
     */
    boolean isRuleEffectiveAtTime(SpatialRule rule, LocalDateTime timestamp);

    /**
     * 检查基本时间窗口匹配
     * @param dailyStartTime 每日开始时间
     * @param dailyEndTime 每日结束时间
     * @param weekdayPattern 星期模式（位掩码）
     * @param timestamp 检查时间
     * @return 如果匹配返回true
     */
    boolean matchesBasicTimeWindow(LocalTime dailyStartTime, LocalTime dailyEndTime, 
                                   Integer weekdayPattern, LocalDateTime timestamp);

    /**
     * 检查复杂时间模式匹配
     * @param timePatterns 时间模式JSON配置
     * @param timestamp 检查时间
     * @return 如果匹配返回true
     */
    boolean matchesComplexTimePatterns(JsonNode timePatterns, LocalDateTime timestamp);

    /**
     * 检查复杂时间模式匹配（String版本）
     * @param timePatternsJson 时间模式JSON字符串
     * @param timestamp 检查时间
     * @return 如果匹配返回true
     */
    boolean matchesComplexTimePatterns(String timePatternsJson, LocalDateTime timestamp);

    /**
     * 检查每日时间范围匹配
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param currentTime 当前时间
     * @return 如果在时间范围内返回true
     */
    boolean matchesDailyTimeRange(LocalTime startTime, LocalTime endTime, LocalTime currentTime);

    /**
     * 检查星期模式匹配
     * @param weekdayPattern 星期模式（位掩码：1=周一, 2=周二, 4=周三, ..., 64=周日）
     * @param timestamp 检查时间
     * @return 如果匹配返回true
     */
    boolean matchesWeekdayPattern(Integer weekdayPattern, LocalDateTime timestamp);

    /**
     * 检查月份模式匹配
     * @param monthPattern 月份模式（位掩码：1=1月, 2=2月, ..., 2048=12月）
     * @param timestamp 检查时间
     * @return 如果匹配返回true
     */
    boolean matchesMonthPattern(Integer monthPattern, LocalDateTime timestamp);

    /**
     * 检查日期范围匹配
     * @param startDate 开始日期（格式：MM-dd）
     * @param endDate 结束日期（格式：MM-dd）
     * @param timestamp 检查时间
     * @return 如果在日期范围内返回true
     */
    boolean matchesDateRange(String startDate, String endDate, LocalDateTime timestamp);

    /**
     * 检查时间间隔模式匹配
     * @param intervalMinutes 间隔分钟数
     * @param offsetMinutes 偏移分钟数
     * @param timestamp 检查时间
     * @return 如果匹配间隔模式返回true
     */
    boolean matchesIntervalPattern(Integer intervalMinutes, Integer offsetMinutes, LocalDateTime timestamp);

    /**
     * 检查节假日模式匹配
     * @param holidayPattern 节假日模式配置
     * @param timestamp 检查时间
     * @return 如果匹配节假日模式返回true
     */
    boolean matchesHolidayPattern(JsonNode holidayPattern, LocalDateTime timestamp);

    /**
     * 检查节假日模式匹配（String版本）
     * @param holidayPatternJson 节假日模式JSON字符串
     * @param timestamp 检查时间
     * @return 如果匹配节假日模式返回true
     */
    boolean matchesHolidayPattern(String holidayPatternJson, LocalDateTime timestamp);

    /**
     * 检查特殊日期模式匹配
     * @param specialDates 特殊日期列表
     * @param timestamp 检查时间
     * @return 如果匹配特殊日期返回true
     */
    boolean matchesSpecialDates(List<String> specialDates, LocalDateTime timestamp);

    /**
     * 获取规则的下次生效时间
     * @param rule 空间规则
     * @param fromTime 起始时间
     * @return 下次生效时间，如果永不生效返回null
     */
    LocalDateTime getNextEffectiveTime(SpatialRule rule, LocalDateTime fromTime);

    /**
     * 获取规则的下次失效时间
     * @param rule 空间规则
     * @param fromTime 起始时间
     * @return 下次失效时间，如果永不失效返回null
     */
    LocalDateTime getNextIneffectiveTime(SpatialRule rule, LocalDateTime fromTime);

    /**
     * 计算规则在指定时间段内的有效时长
     * @param rule 空间规则
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 有效时长（分钟）
     */
    long calculateEffectiveDuration(SpatialRule rule, LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 获取规则在指定日期的有效时间段
     * @param rule 空间规则
     * @param date 指定日期
     * @return 有效时间段列表
     */
    List<TimeWindow> getEffectiveTimeWindows(SpatialRule rule, LocalDateTime date);

    /**
     * 验证时间模式配置的有效性
     * @param timePatterns 时间模式JSON配置
     * @return 验证结果
     */
    TimePatternValidationResult validateTimePatterns(JsonNode timePatterns);

    /**
     * 验证时间模式配置的有效性（String版本）
     * @param timePatternsJson 时间模式JSON字符串
     * @return 验证结果
     */
    TimePatternValidationResult validateTimePatterns(String timePatternsJson);

    /**
     * 解析时间模式字符串
     * @param timePatternString 时间模式字符串（如："MON-FRI 09:00-17:00"）
     * @return 解析后的时间模式对象
     */
    ParsedTimePattern parseTimePatternString(String timePatternString);

    /**
     * 时间窗口类
     * 表示一个具体的时间段
     */
    class TimeWindow {
        private final LocalDateTime startTime;
        private final LocalDateTime endTime;
        private final String description;

        public TimeWindow(LocalDateTime startTime, LocalDateTime endTime, String description) {
            this.startTime = startTime;
            this.endTime = endTime;
            this.description = description;
        }

        public LocalDateTime getStartTime() { return startTime; }
        public LocalDateTime getEndTime() { return endTime; }
        public String getDescription() { return description; }

        public boolean contains(LocalDateTime timestamp) {
            return !timestamp.isBefore(startTime) && !timestamp.isAfter(endTime);
        }

        public long getDurationMinutes() {
            return java.time.Duration.between(startTime, endTime).toMinutes();
        }

        @Override
        public String toString() {
            return String.format("TimeWindow{%s - %s: %s}", startTime, endTime, description);
        }
    }

    /**
     * 时间模式验证结果类
     */
    class TimePatternValidationResult {
        private final boolean valid;
        private final List<String> errors;
        private final List<String> warnings;

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

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

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

    /**
     * 解析后的时间模式类
     */
    class ParsedTimePattern {
        private final List<Integer> weekdays;
        private final LocalTime startTime;
        private final LocalTime endTime;
        private final List<String> specialDates;
        private final boolean excludeHolidays;

        public ParsedTimePattern(List<Integer> weekdays, LocalTime startTime, LocalTime endTime,
                                List<String> specialDates, boolean excludeHolidays) {
            this.weekdays = weekdays;
            this.startTime = startTime;
            this.endTime = endTime;
            this.specialDates = specialDates;
            this.excludeHolidays = excludeHolidays;
        }

        public List<Integer> getWeekdays() { return weekdays; }
        public LocalTime getStartTime() { return startTime; }
        public LocalTime getEndTime() { return endTime; }
        public List<String> getSpecialDates() { return specialDates; }
        public boolean isExcludeHolidays() { return excludeHolidays; }

        @Override
        public String toString() {
            return String.format("ParsedTimePattern{weekdays=%s, time=%s-%s, specialDates=%s, excludeHolidays=%s}",
                               weekdays, startTime, endTime, specialDates, excludeHolidays);
        }
    }
} 