//
//  KBStreamFetcher.h
//  CustomKeyboard
//
//  轻量网络流拉取器：支持纯文本分块与 SSE(text/event-stream) 两种形式的“边下边显”。
//  - 增量解码：按 UTF-8 安全前缀逐步转成字符串，避免半个多字节字符导致阻塞/乱码
//  - SSE 解析：按 \n\n 切事件，合并 data: 行，移除前缀，仅回传正文
//  - 兼容后端“/t”作为分段标记：可自动替换为制表符“\t”
//  - 首段去首个“\t”：若首次正文以一个制表符起始（允许前导空白），可只移除“一个”\t
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef void (^KBStreamFetcherChunkHandler)(NSString *chunk);
typedef void (^KBStreamFetcherFinishHandler)(NSError *_Nullable error);

@interface KBStreamFetcher : NSObject <NSURLSessionDataDelegate>

// 便利构造
+ (instancetype)fetcherWithURL:(NSURL *)url;

// 必填：请求地址
@property (nonatomic, strong) NSURL *url;

// 可选 Header
@property (nonatomic, copy, nullable) NSDictionary<NSString *, NSString *> *extraHeaders;

// 配置项（默认值见注释）
@property (nonatomic, assign) BOOL acceptEventStream;   // 默认 NO；置 YES 时发送 Accept: text/event-stream
@property (nonatomic, assign) BOOL disableCompression;  // 默认 YES；发送 Accept-Encoding: identity
@property (nonatomic, assign) BOOL treatSlashTAsTab;    // 默认 YES；将“/t”替换为“\t”
@property (nonatomic, assign) BOOL trimLeadingTabOnce;  // 默认 YES；首次正文起始的“\t”删一个（忽略前导空白）
@property (nonatomic, assign) NSTimeInterval requestTimeout; // 默认 30s
/// UI 刷新节奏：当一次回调内解析出多段（如多条 SSE 事件）时，按该间隔逐条回调（默认 0.10s）。
@property (nonatomic, assign) NSTimeInterval flushInterval;
/// 非 SSE 且一次性拿到大段文本时，是否按空格切词逐条回调（模拟“逐词流式”），默认 YES。
@property (nonatomic, assign) BOOL splitLargeDeltasOnWhitespace;

/// 调试日志：默认 YES。输出起止时刻、首包耗时、各分片内容（截断）等关键信息。
@property (nonatomic, assign) BOOL loggingEnabled;

// 回调（统一在主线程触发）
@property (nonatomic, copy, nullable) KBStreamFetcherChunkHandler onChunk;
@property (nonatomic, copy, nullable) KBStreamFetcherFinishHandler onFinish;

// 控制
- (void)start;
- (void)cancel;

@end

NS_ASSUME_NONNULL_END
