//
//  KBAlert.m
//  keyBoard
//

#import "KBAlert.h"
#import <UIKit/UIKit.h>
#import "UIViewController+Extension.h"

@implementation KBAlert

// 简单的串行展示队列，避免重复 present 引发的异常
static NSMutableArray<dispatch_block_t> *sQueue;
static BOOL sPresenting = NO;
static __weak UIViewController *sDefaultPresenter = nil; // 可选外部指定的 presenter（弱引用）

#pragma mark - Helpers

+ (void)initialize {
    if (self == KBAlert.class) {
        sQueue = [NSMutableArray array];
    }
}

+ (void)onMain:(dispatch_block_t)blk {
    if (NSThread.isMainThread) { blk(); } else { dispatch_async(dispatch_get_main_queue(), blk); }
}

+ (UIViewController *)presentingVC {
    // 优先使用外部指定的 presenter；否则找顶层
    UIViewController *vc = sDefaultPresenter;
    if (!vc) {
        vc = [UIViewController kb_topMostViewController];
    }
    return vc;
}

+ (void)enqueuePresent:(dispatch_block_t)presenter {
    [self onMain:^{
        [sQueue addObject:[presenter copy]];
        if (!sPresenting) { [self _dequeueAndPresentNext]; }
    }];
}

+ (void)_dequeueAndPresentNext {
    if (sPresenting || sQueue.count == 0) { return; }
    sPresenting = YES;
    dispatch_block_t blk = sQueue.firstObject;
    [sQueue removeObjectAtIndex:0];
    blk();
}

// 在任意 action 执行后调用，标记结束并尝试继续队列
+ (void)_markFinishedAndContinue {
    // 延迟到下一个 runloop 以确保系统完成 dismiss 流程
    dispatch_async(dispatch_get_main_queue(), ^{
        sPresenting = NO;
        [self _dequeueAndPresentNext];
    });
}

// iPad 的 ActionSheet 需要 popover 锚点；此处自动兜底
+ (void)configurePopoverIfNeeded:(UIAlertController *)ac anchorView:(UIView *)anchorView inVC:(UIViewController *)vc {
    if (ac.preferredStyle != UIAlertControllerStyleActionSheet) { return; }
    UIPopoverPresentationController *pop = ac.popoverPresentationController;
    if (!pop) { return; }
    if (anchorView) {
        pop.sourceView = anchorView;
        pop.sourceRect = anchorView.bounds;
    } else if (vc.view) {
        pop.sourceView = vc.view;
        CGSize sz = vc.view.bounds.size;
        CGRect r = CGRectMake(MAX(0, sz.width * 0.5 - 1), MAX(0, sz.height * 0.5 - 1), 2, 2);
        pop.sourceRect = r; // 居中一个很小的矩形，视觉近似居中弹出
        pop.permittedArrowDirections = 0;
    }
}

#pragma mark - Public API

+ (void)setDefaultPresenter:(UIViewController *)presenter { sDefaultPresenter = presenter; }

+ (void)showTitle:(NSString *)title message:(NSString *)message {
    [self showTitle:title message:message button:nil completion:nil];
}

+ (void)showTitle:(NSString *)title
          message:(NSString *)message
           button:(NSString *)button
       completion:(dispatch_block_t)completion {
    [self enqueuePresent:^{
        UIViewController *vc = [self presentingVC];
        if (!vc) { // 无法获取 presenter，直接结束队列
            [self _markFinishedAndContinue];
            return;
        }
        NSString *ok = button ?: (NSLocalizedString(@"OK", nil).length ? NSLocalizedString(@"OK", nil) : @"好");
        UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"")
                                                                   message:(message ?: @"")
                                                            preferredStyle:UIAlertControllerStyleAlert];
        __weak UIAlertController *wac = ac;
        UIAlertAction *okAct = [UIAlertAction actionWithTitle:ok style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction * _Nonnull action) {
            if (completion) { completion(); }
            // 防止异常：确保 alert 被关闭
            [wac dismissViewControllerAnimated:YES completion:nil];
            [KBAlert _markFinishedAndContinue];
        }];
        [ac addAction:okAct];
        [vc presentViewController:ac animated:YES completion:nil];
    }];
}

+ (void)confirmTitle:(NSString *)title message:(NSString *)message completion:(KBAlertBoolHandler)completion {
    [self confirmTitle:title message:message ok:nil cancel:nil completion:completion];
}

+ (void)confirmTitle:(NSString *)title
             message:(NSString *)message
                 ok:(NSString *)okTitle
             cancel:(NSString *)cancelTitle
          completion:(KBAlertBoolHandler)completion {
    [self confirmTitle:title message:message ok:okTitle cancel:cancelTitle okColor:nil cancelColor:nil completion:completion];
}

// KVC 方式设置 action 文字颜色（非公开 API，做保护）
static inline void KBSetActionTitleColor(UIAlertAction *action, UIColor *color) {
    if (!color || !action) return;
    @try { [action setValue:color forKey:@"titleTextColor"]; } @catch (__unused NSException *e) {}
}

+ (void)confirmTitle:(NSString *)title
             message:(NSString *)message
                 ok:(NSString *)okTitle
             cancel:(NSString *)cancelTitle
            okColor:(UIColor *)okColor
        cancelColor:(UIColor *)cancelColor
          completion:(KBAlertBoolHandler)completion {
    [self enqueuePresent:^{
        UIViewController *vc = [self presentingVC];
        if (!vc) { [self _markFinishedAndContinue]; return; }
        NSString *ok = okTitle ?: @"确定";
        NSString *cancel = cancelTitle ?: @"取消";
        UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"")
                                                                   message:(message ?: @"")
                                                            preferredStyle:UIAlertControllerStyleAlert];
        __weak UIAlertController *wac = ac;
        UIAlertAction *cancelAct = [UIAlertAction actionWithTitle:cancel style:UIAlertActionStyleCancel handler:^(__unused UIAlertAction * _Nonnull a) {
            if (completion) { completion(NO); }
            [wac dismissViewControllerAnimated:YES completion:nil];
            [KBAlert _markFinishedAndContinue];
        }];
        UIAlertAction *okAct = [UIAlertAction actionWithTitle:ok style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction * _Nonnull a) {
            if (completion) { completion(YES); }
            [wac dismissViewControllerAnimated:YES completion:nil];
            [KBAlert _markFinishedAndContinue];
        }];
        // 自定义颜色
        KBSetActionTitleColor(okAct, okColor);
        KBSetActionTitleColor(cancelAct, cancelColor);

        [ac addAction:cancelAct];
        [ac addAction:okAct];
        [vc presentViewController:ac animated:YES completion:nil];
    }];
}

+ (void)promptTitle:(NSString *)title
            message:(NSString *)message
        placeholder:(NSString *)placeholder
                 ok:(NSString *)okTitle
             cancel:(NSString *)cancelTitle
      keyboardType:(UIKeyboardType)type
     configuration:(void (^)(UITextField * _Nonnull))config
          completion:(KBAlertTextHandler)completion {
    [self enqueuePresent:^{
        UIViewController *vc = [self presentingVC];
        if (!vc) { [self _markFinishedAndContinue]; return; }
        NSString *ok = okTitle ?: @"确定";
        NSString *cancel = cancelTitle ?: @"取消";
        UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"")
                                                                   message:(message ?: @"")
                                                            preferredStyle:UIAlertControllerStyleAlert];
        __weak UIAlertController *wac = ac;
        [ac addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull tf) {
            tf.placeholder = placeholder;
            tf.keyboardType = type;
            if (config) { config(tf); }
        }];
        UIAlertAction *cancelAct = [UIAlertAction actionWithTitle:cancel style:UIAlertActionStyleCancel handler:^(__unused UIAlertAction * _Nonnull a) {
            if (completion) { completion(nil, NO); }
            [wac dismissViewControllerAnimated:YES completion:nil];
            [KBAlert _markFinishedAndContinue];
        }];
        UIAlertAction *okAct = [UIAlertAction actionWithTitle:ok style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction * _Nonnull a) {
            NSString *text = wac.textFields.firstObject.text;
            if (completion) { completion(text, YES); }
            [wac dismissViewControllerAnimated:YES completion:nil];
            [KBAlert _markFinishedAndContinue];
        }];
        [ac addAction:cancelAct];
        [ac addAction:okAct];
        [vc presentViewController:ac animated:YES completion:nil];
    }];
}

+ (void)actionSheetTitle:(NSString *)title
                 message:(NSString *)message
                 actions:(NSArray<NSString *> *)actions
                  cancel:(NSString *)cancelTitle
       destructiveIndex:(NSInteger)destructiveIndex
                fromView:(UIView *)anchorView
               completion:(KBAlertIndexHandler)completion {
    [self enqueuePresent:^{
        UIViewController *vc = [self presentingVC];
        if (!vc) { [self _markFinishedAndContinue]; return; }
        UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"")
                                                                   message:(message ?: @"")
                                                            preferredStyle:UIAlertControllerStyleActionSheet];
        __weak UIAlertController *wac = ac;
        [actions enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            UIAlertActionStyle style = (destructiveIndex >= 0 && (NSInteger)idx == destructiveIndex) ? UIAlertActionStyleDestructive : UIAlertActionStyleDefault;
            UIAlertAction *act = [UIAlertAction actionWithTitle:obj ?: @"" style:style handler:^(__unused UIAlertAction * _Nonnull a) {
                if (completion) { completion((NSInteger)idx); }
                [wac dismissViewControllerAnimated:YES completion:nil];
                [KBAlert _markFinishedAndContinue];
            }];
            [ac addAction:act];
        }];
        if (cancelTitle.length) {
            UIAlertAction *cancel = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:^(__unused UIAlertAction * _Nonnull a) {
                if (completion) { completion(-1); }
                [wac dismissViewControllerAnimated:YES completion:nil];
                [KBAlert _markFinishedAndContinue];
            }];
            [ac addAction:cancel];
        }

        [self configurePopoverIfNeeded:ac anchorView:anchorView inVC:vc];
        [vc presentViewController:ac animated:YES completion:nil];
    }];
}

@end
