#import "TQUIDelegate.h"
#import "TQL10n.h"
#import "TQSdkEvent.h"

@interface TQUIDelegate ()
@property (nonatomic, copy, nullable) TQOnEventBlock onEvent;
@property (nonatomic, weak, nullable) UIViewController *hostingController;
@end

@implementation TQUIDelegate

- (instancetype)initWithOnEvent:(TQOnEventBlock)onEvent
              hostingController:(UIViewController *)hostingController {
    if (self = [super init]) {
        _onEvent = [onEvent copy];
        _hostingController = hostingController;
    }
    return self;
}

#pragma mark - 媒体权限(iOS 15+)

- (void)webView:(WKWebView *)webView
    requestMediaCapturePermissionForOrigin:(WKSecurityOrigin *)origin
    initiatedByFrame:(WKFrameInfo *)frame
    type:(WKMediaCaptureType)type
    decisionHandler:(void (^)(WKPermissionDecision))decisionHandler API_AVAILABLE(ios(15.0)) {
    // 直接 grant,无域名校验(详见 design.md)
    decisionHandler(WKPermissionDecisionGrant);

    NSArray<NSString *> *perms;
    switch (type) {
        case WKMediaCaptureTypeCamera:              perms = @[ @"camera" ]; break;
        case WKMediaCaptureTypeMicrophone:          perms = @[ @"microphone" ]; break;
        case WKMediaCaptureTypeCameraAndMicrophone: perms = @[ @"camera", @"microphone" ]; break;
        default:                                    perms = @[]; break;
    }
    if (self.onEvent) {
        self.onEvent([[TQPermissionGrantedEvent alloc] initWithPermissions:perms]);
    }
}

#pragma mark - target=_blank 处理

- (WKWebView *)webView:(WKWebView *)webView
    createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration
    forNavigationAction:(WKNavigationAction *)navigationAction
    windowFeatures:(WKWindowFeatures *)windowFeatures {
    // 用当前 webView 加载,避免新窗口
    NSURL *url = navigationAction.request.URL;
    if (url) {
        [webView loadRequest:[NSURLRequest requestWithURL:url]];
    }
    return nil;
}

#pragma mark - JS alert / confirm / prompt

- (void)webView:(WKWebView *)webView
    runJavaScriptAlertPanelWithMessage:(NSString *)message
    initiatedByFrame:(WKFrameInfo *)frame
    completionHandler:(void (^)(void))completionHandler {
    UIViewController *host = self.hostingController ?: [self topViewControllerOfView:webView];
    if (host == nil || ![self canPresentOn:host]) { completionHandler(); return; }
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:[TQL10n jsOK]
                                              style:UIAlertActionStyleDefault
                                            handler:^(UIAlertAction *_) { completionHandler(); }]];
    [host presentViewController:alert animated:YES completion:nil];
}

- (void)webView:(WKWebView *)webView
    runJavaScriptConfirmPanelWithMessage:(NSString *)message
    initiatedByFrame:(WKFrameInfo *)frame
    completionHandler:(void (^)(BOOL))completionHandler {
    UIViewController *host = self.hostingController ?: [self topViewControllerOfView:webView];
    if (host == nil || ![self canPresentOn:host]) { completionHandler(NO); return; }
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:[TQL10n jsCancel]
                                              style:UIAlertActionStyleCancel
                                            handler:^(UIAlertAction *_) { completionHandler(NO); }]];
    [alert addAction:[UIAlertAction actionWithTitle:[TQL10n jsOK]
                                              style:UIAlertActionStyleDefault
                                            handler:^(UIAlertAction *_) { completionHandler(YES); }]];
    [host presentViewController:alert animated:YES completion:nil];
}

- (void)webView:(WKWebView *)webView
    runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt
    defaultText:(NSString *)defaultText
    initiatedByFrame:(WKFrameInfo *)frame
    completionHandler:(void (^)(NSString * _Nullable))completionHandler {
    UIViewController *host = self.hostingController ?: [self topViewControllerOfView:webView];
    if (host == nil || ![self canPresentOn:host]) { completionHandler(nil); return; }
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
                                                                   message:prompt
                                                            preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
        textField.text = defaultText;
    }];
    [alert addAction:[UIAlertAction actionWithTitle:[TQL10n jsCancel]
                                              style:UIAlertActionStyleCancel
                                            handler:^(UIAlertAction *_) { completionHandler(nil); }]];
    __weak UIAlertController *weakAlert = alert;
    [alert addAction:[UIAlertAction actionWithTitle:[TQL10n jsOK]
                                              style:UIAlertActionStyleDefault
                                            handler:^(UIAlertAction *_) {
        completionHandler(weakAlert.textFields.firstObject.text);
    }]];
    [host presentViewController:alert animated:YES completion:nil];
}

#pragma mark - utils

/// 检查 ViewController 是否可以安全地 present 弹窗。
///
/// **背景**:当 host 不为 nil 但其 view 已不在 window 层级中时
/// (例如正在 dismiss 动画中、或已被 pop),`present` 会抛出 warning
/// 或在 iOS 13 以下 crash。Android 端已有 `isFinishing/isDestroyed` 检查,
/// 此处为 iOS 等价保护。
- (BOOL)canPresentOn:(UIViewController *)vc {
    if (vc.isBeingDismissed || vc.isBeingPresented) return NO;
    if (vc.view.window == nil) return NO;
    return YES;
}

- (nullable UIViewController *)topViewControllerOfView:(UIView *)view {
    UIResponder *responder = view;
    while (responder) {
        if ([responder isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)responder;
        }
        responder = responder.nextResponder;
    }
    return nil;
}

@end
