//
//  HistoryPreloader.m
//  AIIM
//
//  Created by qitewei on 2025/5/20.
//

#import "HistoryPreloader.h"
#import <objc/runtime.h>

@interface HistoryPreloader() {
    CADisplayLink *_displayLink;
    CGFloat _initialOffset;
    BOOL _isUserInitiatedScroll;
    NSTimeInterval _lastTriggerTime;
    CGFloat _lastScrollVelocity;
}

@end

@implementation HistoryPreloader

- (instancetype)init {
    self = [super init];
    if (self) {
        _threshold = 300.0; // 默认阈值
        _initialOffset = CGFLOAT_MAX;
    }
    return self;
}

- (void)dealloc {
    [self stopMonitoring];
}

#pragma mark - 公共方法

- (void)startMonitoring {
    if (_displayLink) return;
    
    // 记录初始偏移量（考虑contentInset）
    _initialOffset = -self.tableView.contentInset.top;
    _isUserInitiatedScroll = NO;
    
    // 设置DisplayLink监控滚动
    _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleScrollCheck)];
    [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)stopMonitoring {
    [_displayLink invalidate];
    _displayLink = nil;
}

- (void)resetScrollState {
    _isUserInitiatedScroll = NO;
    _initialOffset = -self.tableView.contentInset.top;
}

#pragma mark - 私有方法

- (void)handleScrollCheck {
    CGFloat currentOffset = self.tableView.contentOffset.y;
    
    // 1. 检测是否是用户发起的滑动
    if (!_isUserInitiatedScroll) {
        // 使用5pt的阈值避免误判
        if (fabs(currentOffset - _initialOffset) > 5.0) {
            _isUserInitiatedScroll = YES;
        } else {
            return; // 未滑动，直接返回
        }
    }
    
    // 2. 计算滚动速度（用于动态调整阈值）
    CFTimeInterval timestamp = _displayLink.timestamp;
    static CFTimeInterval lastTimestamp = 0;
    if (lastTimestamp != 0) {
        _lastScrollVelocity = (currentOffset - _lastScrollVelocity) / (timestamp - lastTimestamp);
    }
    lastTimestamp = timestamp;
    _lastScrollVelocity = currentOffset;
    
    // 3. 动态调整阈值（可选）
    CGFloat dynamicThreshold = [self dynamicThresholdBasedOnVelocity:_lastScrollVelocity];
    
    // 4. 检查是否需要触发预加载
    if (currentOffset < dynamicThreshold) {
        [self tryTriggerPreload];
    }
}

- (CGFloat)dynamicThresholdBasedOnVelocity:(CGFloat)velocity {
    // 基础阈值
    CGFloat baseThreshold = self.threshold;
    
    // 根据滚动速度调整（速度越快，阈值越大，提前触发）
    if (fabs(velocity) > 100) { // 快速滚动
        return baseThreshold * 1.5;
    } else if (fabs(velocity) < 20) { // 慢速滚动
        return baseThreshold * 0.8;
    }
    return baseThreshold;
}

- (void)tryTriggerPreload {
    // 冷却时间检查（至少间隔1秒）
    NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
    if (now - _lastTriggerTime < 1.0){
        // 触发过快加载加载回调
        if (self.toofast) {
            self.toofast();
        }
        return;
    }
    
    _lastTriggerTime = now;
    
    // 触发加载回调
    if (self.loadBlock) {
        self.loadBlock();
    }
    
    // 短暂停止监控防止连续触发
    [self stopMonitoring];
    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf startMonitoring];
    });
}

#pragma mark - 只读属性访问

- (BOOL)isUserInitiatedScroll {
    return _isUserInitiatedScroll;
}


@end
