//
//  KBNetworkManager.m
//  CustomKeyboard
//

#import "KBNetworkManager.h"
#import "AFNetworking.h"

NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";

@interface KBNetworkManager ()
@property (nonatomic, strong) AFHTTPSessionManager *manager; // AFN 管理器（ephemeral 配置）
// 私有错误派发
- (void)fail:(KBNetworkError)code completion:(KBNetworkCompletion)completion;
@end

@implementation KBNetworkManager

+ (instancetype)shared {
    static KBNetworkManager *m; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ m = [KBNetworkManager new]; });
    return m;
}

- (instancetype)init {
    if (self = [super init]) {
        _enabled = NO; // 键盘扩展默认无网络能力，需外部显式开启
        _timeout = 10.0;
        _defaultHeaders = @{ @"Accept": @"application/json" };
    }
    return self;
}

#pragma mark - Public

- (NSURLSessionDataTask *)GET:(NSString *)path
                     parameters:(NSDictionary *)parameters
                        headers:(NSDictionary<NSString *,NSString *> *)headers
                      completion:(KBNetworkCompletion)completion {
    if (![self ensureEnabled:completion]) return nil;
    NSString *urlString = [self buildURLStringWithPath:path];
    if (!urlString) { [self fail:KBNetworkErrorInvalidURL completion:completion]; return nil; }
    // 使用 AFHTTPRequestSerializer 生成带参数与头的请求
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
    serializer.timeoutInterval = self.timeout;
    NSMutableURLRequest *req = [serializer requestWithMethod:@"GET"
                                                   URLString:urlString
                                                  parameters:parameters
                                                       error:NULL];
    [self applyHeaders:headers toMutableRequest:req contentType:nil];
    return [self startAFTaskWithRequest:req completion:completion];
}

- (NSURLSessionDataTask *)POST:(NSString *)path
                       jsonBody:(id)jsonBody
                        headers:(NSDictionary<NSString *,NSString *> *)headers
                      completion:(KBNetworkCompletion)completion {
    if (![self ensureEnabled:completion]) return nil;
    NSString *urlString = [self buildURLStringWithPath:path];
    if (!urlString) { [self fail:KBNetworkErrorInvalidURL completion:completion]; return nil; }
    // 用 JSON 序列化器生成 JSON Body 的请求
    AFJSONRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
    serializer.timeoutInterval = self.timeout;
    NSError *error = nil;
    NSMutableURLRequest *req = [serializer requestWithMethod:@"POST"
                                                   URLString:urlString
                                                  parameters:jsonBody
                                                       error:&error];
    if (error) { if (completion) completion(nil, nil, error); return nil; }
    [self applyHeaders:headers toMutableRequest:req contentType:nil];
    return [self startAFTaskWithRequest:req completion:completion];
}

#pragma mark - Core

- (BOOL)ensureEnabled:(KBNetworkCompletion)completion {
    if (!self.isEnabled) {
        NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: @"网络未启用（可能未开启完全访问）"}];
        if (completion) completion(nil, nil, e);
        return NO;
    }
    return YES;
}

- (NSString *)buildURLStringWithPath:(NSString *)path {
    if (path.length == 0) return nil;
    if ([path hasPrefix:@"http://"] || [path hasPrefix:@"https://"]) {
        return path;
    }
    if (self.baseURL) {
        return [NSURL URLWithString:path relativeToURL:self.baseURL].absoluteURL.absoluteString;
    }
    return path; // 当无 baseURL 且 path 不是完整 URL 时，让 AFN 处理（可能失败）
}

- (void)applyHeaders:(NSDictionary<NSString *,NSString *> *)headers toMutableRequest:(NSMutableURLRequest *)req contentType:(NSString *)contentType {
    // 合并默认头与局部头，局部覆盖
    NSMutableDictionary *all = [self.defaultHeaders mutableCopy] ?: [NSMutableDictionary new];
    if (contentType) all[@"Content-Type"] = contentType;
    [headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { all[key] = obj; }];
    [all enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { [req setValue:obj forHTTPHeaderField:key]; }];
}

- (NSURLSessionDataTask *)startAFTaskWithRequest:(NSURLRequest *)req completion:(KBNetworkCompletion)completion {
    // 响应先用原始数据返回，再按 Content-Type 解析 JSON（与原实现一致）
    self.manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    NSURLSessionDataTask *task = [self.manager dataTaskWithRequest:req uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        if (error) { if (completion) completion(nil, response, error); return; }
        NSData *data = (NSData *)responseObject;
        if (![data isKindOfClass:[NSData class]]) {
            if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:@"无数据"}]);
            return;
        }
        NSString *ct = nil;
        if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
            ct = ((NSHTTPURLResponse *)response).allHeaderFields[@"Content-Type"];
        }
        BOOL looksJSON = (ct && [ct.lowercaseString containsString:@"application/json"]);
        if (looksJSON) {
            NSError *jsonErr = nil;
            id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonErr];
            if (jsonErr) { if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:@"JSON解析失败"}]); return; }
            if (completion) completion(json, response, nil);
        } else {
            if (completion) completion(data, response, nil);
        }
    }];
    [task resume];
    return task;
}

#pragma mark - AFHTTPSessionManager

- (AFHTTPSessionManager *)manager {
    if (!_manager) {
        NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration ephemeralSessionConfiguration];
        cfg.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
        cfg.timeoutIntervalForRequest = self.timeout;
        cfg.timeoutIntervalForResource = MAX(self.timeout, 30.0);
        if (@available(iOS 11.0, *)) { cfg.waitsForConnectivity = YES; }
        _manager = [[AFHTTPSessionManager alloc] initWithBaseURL:nil sessionConfiguration:cfg];
        // 默认不使用 JSON 解析器，保持原生数据，再按需解析
        _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    }
    return _manager;
}

#pragma mark - Private helpers

- (void)fail:(KBNetworkError)code completion:(KBNetworkCompletion)completion {
    NSString *msg = @"网络错误";
    switch (code) {
        case KBNetworkErrorDisabled: msg = @"网络未启用（可能未开启完全访问）"; break;
        case KBNetworkErrorInvalidURL: msg = @"无效的URL"; break;
        case KBNetworkErrorInvalidResponse: msg = @"无效的响应"; break;
        case KBNetworkErrorDecodeFailed: msg = @"解析失败"; break;
        default: break;
    }
    NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain
                                     code:code
                                 userInfo:@{NSLocalizedDescriptionKey: msg}];
    if (completion) completion(nil, nil, e);
}

@end
