#import "TQSchemeInterceptor.h"
#import "TQSignResultParser.h"
#import <UIKit/UIKit.h>

#pragma mark - TQSchemeInterceptor

@implementation TQSchemeInterceptor {
    TQOnSignResultBlock _onSignResult;
    TQOnEventBlock _onEvent;
}

- (instancetype)initWithOnSignResult:(TQOnSignResultBlock)onSignResult
                             onEvent:(TQOnEventBlock)onEvent {
    if (self = [super init]) {
        _onSignResult = [onSignResult copy];
        _onEvent = [onEvent copy];
    }
    return self;
}

- (BOOL)handle:(NSString *)urlString {
    if (![TQSignResultParser isQianAppScheme:urlString]) return NO;
    TQSignResult *result = [TQSignResultParser parse:urlString];
    NSString *capturedUrl = [urlString copy] ?: @"";
    __weak __typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        __strong __typeof(weakSelf) self = weakSelf;
        if (!self) return;
        if (self->_onSignResult) self->_onSignResult(result);
        if (self->_onEvent) {
            self->_onEvent([[TQSchemeInterceptedEvent alloc] initWithScheme:@"qianapp"
                                                                        url:capturedUrl]);
        }
    });
    return YES;
}

@end


#pragma mark - TQExternalSchemeHandler

@implementation TQExternalSchemeHandler {
    NSArray<NSString *> *_externalSchemes;
    TQOnEventBlock _onEvent;
}

- (instancetype)initWithExternalSchemes:(NSArray<NSString *> *)externalSchemes
                                onEvent:(TQOnEventBlock)onEvent {
    if (self = [super init]) {
        _externalSchemes = [externalSchemes copy] ?: @[];
        _onEvent = [onEvent copy];
    }
    return self;
}

- (BOOL)tryOpen:(NSString *)urlString {
    if (urlString.length == 0) return NO;
    NSURL *url = [NSURL URLWithString:urlString];
    if (url == nil) return NO;
    NSString *scheme = [url.scheme lowercaseString];
    if (scheme.length == 0) return NO;

    if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) return NO;
    if ([scheme isEqualToString:@"qianapp"]) return NO;

    BOOL matched = NO;
    for (NSString *s in _externalSchemes) {
        if ([[s lowercaseString] isEqualToString:scheme]) {
            matched = YES;
            break;
        }
    }
    if (!matched) {
        if (_onEvent) {
            _onEvent([[TQSchemeNotMatchedEvent alloc] initWithUrl:urlString]);
        }
        return YES;
    }

    // 主线程调用 UIApplication.openURL
    if ([NSThread isMainThread]) {
        [self doOpen:url scheme:scheme urlString:urlString];
    } else {
        __weak __typeof(self) weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf doOpen:url scheme:scheme urlString:urlString];
        });
    }
    return YES;
}

- (void)doOpen:(NSURL *)url scheme:(NSString *)scheme urlString:(NSString *)urlString {
    if (![[UIApplication sharedApplication] canOpenURL:url]) {
        if (_onEvent) {
            _onEvent([[TQSchemeNotMatchedEvent alloc] initWithUrl:urlString]);
        }
        return;
    }
    __weak __typeof(self) weakSelf = self;
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL ok) {
        __strong __typeof(weakSelf) self = weakSelf;
        if (!self || !self->_onEvent) return;
        if (ok) {
            self->_onEvent([[TQSchemeInterceptedEvent alloc] initWithScheme:scheme url:urlString]);
        } else {
            self->_onEvent([[TQSchemeNotMatchedEvent alloc] initWithUrl:urlString]);
        }
    }];
}

@end
