//
//  XXGFloatView.m
//  XXGPlayKit
//
//  Created by apple on 2025/3/13.
//

#import "XXGFloatView.h"
#import "UIImageView+WebCache.h"
#import "UIImage+XXGImage.h"
#import "XXGUIDriver.h"
#import "NSString+XXGString.h"
#import "XXGAlertView.h"
#import "XXGTransparentWindow.h"
#import "XXGOrientationViewController.h"
#import "UIDevice+XXGDevice.h"
#import "XXGWindowManager.h"

@interface XXGFloatView()  <UIGestureRecognizerDelegate> {
    CGPoint _xxpk_originalPosition;
    BOOL _xxpk_isAnimating;
    BOOL _xxpk_hasTriggeredFeedback; // 新增震动触发标记
    BOOL _xxpk_isInHideArea; // 新增标记，记录是否在隐藏区域内
}

// Window相关
@property (nonatomic, strong) XXGTransparentWindow *xxpk_floatWindow;
@property (nonatomic, weak) UIWindow *xxpk_hostKeyWindow;

// UI元素
@property (nonatomic, strong) UIImageView *xxpk_iconView;
@property (nonatomic, strong) UIView *xxpk_redDotView;

// 新增属性
@property (nonatomic, strong) UIView *xxpk_hintView;
@property (nonatomic, strong) UILabel *xxpk_hintLabel;
@property (nonatomic, assign) BOOL xxpk_shouldHide;

// 状态管理
@property (nonatomic, strong) NSTimer *xxpk_autoHideTimer;
@property (nonatomic, assign) UIEdgeInsets xxpk_safeAreaInsets;
@property (nonatomic, assign) CGRect xxpk_lastScreenBounds;

// 配置参数
@property (nonatomic, strong) UIImage *xxpk_normalImage;
@property (nonatomic, copy) NSString *xxpk_normalImageUrl;
@property (nonatomic, strong) UIImage *xxpk_edgeImage;
@property (nonatomic, assign) CGFloat xxpk_edgeInset;
@property (nonatomic, assign) XXGFloatViewEdge xxpk_currentEdge;
@property (nonatomic, assign) NSTimeInterval xxpk_autoHideDelay;
@property (nonatomic, assign) BOOL xxpk_autoEdgeEnabled;
@end

@implementation XXGFloatView

#pragma mark - 生命周期管理
+ (instancetype)shared {
    static XXGFloatView *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[super alloc] initWithFrame:CGRectZero];
        [instance xxpk_setupDefaults];
    });
    return instance;
}

- (UIView *)xxpk_redDotView {
    if (!_xxpk_redDotView) {
        _xxpk_redDotView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 8, 8)];
        _xxpk_redDotView.backgroundColor = UIColor.redColor;
        _xxpk_redDotView.layer.cornerRadius = 4;
        _xxpk_redDotView.hidden = YES;
    }
    return _xxpk_redDotView;
}

- (void)xxpk_setupDefaults {
    self.xxpk_edgeInset = 10.0;
    self.xxpk_autoHideDelay = 3.0;
    self.xxpk_autoEdgeEnabled = YES;
    
    // 初始化视图
    self.xxpk_iconView = [[UIImageView alloc] init];
    self.xxpk_iconView.contentMode = UIViewContentModeScaleAspectFit;
    [self addSubview:self.xxpk_iconView];
    
    self.xxpk_hintView = [[UIView alloc] init];
    self.xxpk_hintView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7];
    self.xxpk_hintView.layer.cornerRadius = 20;
    self.xxpk_hintView.layer.masksToBounds = YES;
    self.xxpk_hintView.alpha = 0.0;
    
    self.xxpk_hintLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 40)];
    self.xxpk_hintLabel.text = XXGUIDriver.xxpk_string_ui.xxpk_floatview_hintlabel;
    self.xxpk_hintLabel.numberOfLines = 0;
    self.xxpk_hintLabel.textColor = [UIColor whiteColor];
    self.xxpk_hintLabel.textAlignment = NSTextAlignmentCenter;
    self.xxpk_hintLabel.font = [UIFont systemFontOfSize:14];
    [self.xxpk_hintView addSubview:self.xxpk_hintLabel];
    
    // 手势配置
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(xxpk_handlePan:)];
    pan.delegate = self;
    [self addGestureRecognizer:pan];
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(xxpk_handleTap)];
    [self addGestureRecognizer:tap];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    // 监听设备方向变化
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(xxpk_handleOrientationChange)
                                                 name:UIApplicationDidChangeStatusBarOrientationNotification
                                               object:nil];
#pragma clang diagnostic pop
}

- (void)setXxpk_redotJson:(NSDictionary *)xxpk_redotJson {
    _xxpk_redotJson = xxpk_redotJson;
    if (xxpk_redotJson && self.xxpk_floatWindow != nil) {
        NSString *action = xxpk_redotJson[XXGUIDriver.xxpk_data_ui.xxpk_ui_action];
        if ([action isEqualToString:XXGUIDriver.xxpk_data_ui.xxpk_ui_show]) {
            self.xxpk_redDotView.hidden = NO;
        }else if ([action isEqualToString:XXGUIDriver.xxpk_data_ui.xxpk_ui_hide]) {
            self.xxpk_redDotView.hidden = YES;
        }else if ([action isEqualToString:XXGUIDriver.xxpk_data_ui.xxpk_ui_show_once]) {
            self.xxpk_redDotView.hidden = NO;
        }
    }
}

#pragma mark - 类方法接口
+ (void)xxpk_show {
    [self.shared xxpk_privateShowWithImage:[UIImage xxpk_imageBundleOfName:XXGUIDriver.xxpk_data_ui.xxpk_img_float_ball] imageUrl:XXGUIDriver.xxpk_docker_image edgeImage:nil];
}

+ (void)xxpk_showWithImage:(UIImage *)image {
    [[self shared] xxpk_privateShowWithImage:image edgeImage:nil];
}

+ (void)xxpk_updateImage:(UIImage *)normalImage edgeImage:(nullable UIImage *)edgeImage {
    XXGFloatView *instance = [self shared];
    instance.xxpk_normalImage = normalImage;
    instance.xxpk_normalImageUrl = nil;
    instance.xxpk_edgeImage = edgeImage;
    instance.xxpk_iconView.image = normalImage;
}

+ (void)xxpk_hide {
    [[self shared] xxpk_privateHide];
}

+ (BOOL)xxpk_isShowing {
    return [self shared].xxpk_floatWindow != nil;
}

#pragma mark - 核心显示逻辑
- (void)xxpk_privateShowWithImage:(UIImage *)image edgeImage:(nullable UIImage *)edgeImage {
    [self xxpk_privateShowWithImage:image imageUrl:nil edgeImage:edgeImage];
}

- (void)xxpk_privateShowWithImage:(UIImage *)image imageUrl:(NSString *)imageUrl edgeImage:(nullable UIImage *)edgeImage {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.xxpk_normalImage = image;
        self.xxpk_normalImageUrl = imageUrl;
        self.xxpk_edgeImage = edgeImage;
        
        if (!self.xxpk_floatWindow) {
            [self xxpk_createFloatWindow];
            [self xxpk_updateSafeArea];
            [self xxpk_resetToInitialPosition];
            [self xxpk_updateHintViewLayout]; // 初始化提示视图位置
        }
        
        [self.xxpk_floatWindow makeKeyAndVisible];
        [self.xxpk_hostKeyWindow makeKeyWindow];
        
        [self xxpk_moveToNearestEdgeWithAnimation:YES];
        [self xxpk_startAutoHideTimer];
    });
}

- (void)xxpk_privateHide {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.xxpk_floatWindow resignKeyWindow];
        self.xxpk_floatWindow.hidden = YES;
        self.xxpk_floatWindow = nil;
    });
}

#pragma mark - 窗口管理
- (void)xxpk_createFloatWindow {
    // 记录宿主窗口
    self.xxpk_hostKeyWindow = [self xxpk_findHostKeyWindow];
    
    // 创建悬浮窗口
    XXGTransparentWindow *window = nil;
    
    // 多场景适配（iOS13+）
    if (@available(iOS 13.0, *)) {
        for (UIScene *scene in [UIApplication sharedApplication].connectedScenes) {
            if (scene.activationState == UISceneActivationStateForegroundActive &&
                [scene isKindOfClass:[UIWindowScene class]]) {
                window = [[XXGTransparentWindow alloc] initWithWindowScene:(UIWindowScene *)scene];
                break;
            }
        }
    }
    
    // 兜底创建
    if (!window) {
        window = [[XXGTransparentWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    }
    
    // 基础配置
    window.backgroundColor = [UIColor clearColor];
    window.clipsToBounds = YES; // 确保超出部分不显示
    window.windowLevel = UIWindowLevelAlert + 1000;
    window.backgroundColor = [UIColor clearColor];
    window.rootViewController = [[XXGOrientationViewController alloc] init];
    window.hidden = NO;
    self.xxpk_floatWindow = window;
    
    // 主动放弃KeyWindow状态
    [self.xxpk_floatWindow resignKeyWindow];
    [self.xxpk_hostKeyWindow makeKeyWindow];
    
    // 设置红点
    [self addSubview:self.xxpk_redDotView];
    
    // 设置按钮属性
    self.frame = CGRectMake(0, 0, 60, 60);
    if (self.xxpk_normalImageUrl) {
        [self.xxpk_iconView sd_setImageWithURL:[NSURL URLWithString:self.xxpk_normalImageUrl] placeholderImage
                                              :[UIImage xxpk_imageBundleOfName:XXGUIDriver.xxpk_data_ui.xxpk_img_float_ball]
                                       options:(SDWebImageDelayPlaceholder)];
    }else {
        self.xxpk_iconView.image = self.xxpk_normalImage;
    }
    self.xxpk_iconView.frame = self.bounds;
    
    [self.xxpk_floatWindow addSubview:self];
    [self.xxpk_floatWindow addSubview:self.xxpk_hintView];
}

// 更新提示视图形状和位置的方法
- (void)xxpk_updateHintViewLayout {
    CGRect screenBounds = self.xxpk_lastScreenBounds;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
#pragma clang diagnostic pop
    // 横屏布局
    if (UIInterfaceOrientationIsLandscape(orientation)) {
        CGFloat hintS = 180;
        self.xxpk_hintView.frame = CGRectMake(
         (screenBounds.size.width - hintS)/2,
          screenBounds.size.height - hintS/2,
          hintS,
          hintS
        );
        self.xxpk_hintView.layer.masksToBounds = YES;
        self.xxpk_hintView.layer.cornerRadius = hintS/2;
        self.xxpk_hintLabel.center = CGPointMake(hintS/2, hintS/4);
    }
    // 竖屏布局
    else {
        CGFloat hintS = 240;
        self.xxpk_hintView.frame = CGRectMake(
//          (screenBounds.size.width - hintS)/2,
          (screenBounds.size.width - hintS/2),
          screenBounds.size.height - hintS/2,
          hintS,
          hintS
        );
        self.xxpk_hintView.layer.masksToBounds = YES;
        self.xxpk_hintView.layer.cornerRadius = hintS/2;
        self.xxpk_hintLabel.center = CGPointMake(hintS/3, hintS/4);
    }
}

#pragma mark - 手势处理
- (void)xxpk_handleTap {
    if (self.xxpk_redotJson) {
        !self.xxpk_tapHandler ?: self.xxpk_tapHandler(self.xxpk_redotJson[XXGUIDriver.xxpk_data_ui.xxpk_ui_url]);
        if ([self.xxpk_redotJson[XXGUIDriver.xxpk_data_ui.xxpk_ui_action] isEqualToString:XXGUIDriver.xxpk_data_ui.xxpk_ui_show_once]) {
            self.xxpk_redDotView.hidden = YES;
            _xxpk_redotJson = nil;
        }
    }else {
        !self.xxpk_tapHandler ?: self.xxpk_tapHandler(nil);
    }
}

- (void)xxpk_handlePan:(UIPanGestureRecognizer *)gesture {
    if (_xxpk_isAnimating) return;
        
    CGPoint translation = [gesture translationInView:self.superview];
    
    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:
            _xxpk_originalPosition = self.center;
            _xxpk_iconView.alpha = 1;
            [self xxpk_cancelAutoHide];
            _xxpk_hasTriggeredFeedback = NO; // 重置震动标记
            _xxpk_isInHideArea = NO; // 重置隐藏区域标记
            
            // 开始拖动时取消所有正在进行的动画
            [self.layer removeAllAnimations];
            [self.xxpk_hintView.layer removeAllAnimations];
            
            // 确保提示视图初始状态
            self.xxpk_hintView.alpha = 0.0;
            self.xxpk_hintView.transform = CGAffineTransformIdentity;
            break;
            
        case UIGestureRecognizerStateChanged:{
            // 计算新位置
            self.center = [self xxpk_adjustedCenterForProposedCenter:
                           CGPointMake(_xxpk_originalPosition.x + translation.x,
                                       _xxpk_originalPosition.y + translation.y)];
            
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
            // 检测是否进入隐藏区域
            BOOL IsLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
#pragma clang diagnostic pop
            CGRect hintFrame = self.xxpk_hintView.frame;
            CGRect touchArea = CGRectInset(hintFrame, -280, IsLandscape?-100:-280); // 扩大检测区域
            BOOL isInHideArea = CGRectContainsPoint(touchArea, self.center);
            
            
            
            // 只有当状态发生变化时才执行动画，减少不必要的动画
            if (isInHideArea != _xxpk_isInHideArea) {
                _xxpk_isInHideArea = isInHideArea;
                
                // 使用UIView动画替代CATransaction，确保动画效果明显
                [UIView animateWithDuration:0.3
                                      delay:0
                                    options:UIViewAnimationOptionBeginFromCurrentState
                                 animations:^{
                    self.xxpk_hintView.alpha = isInHideArea ? 1.0 : 0.0;
                    self.xxpk_hintView.transform = isInHideArea ? CGAffineTransformMakeScale(1.2, 1.2) : CGAffineTransformIdentity;
                } completion:nil];
            }
            
            // 震动反馈（只在进入区域时触发一次）
            isInHideArea = CGRectContainsPoint(CGRectInset(hintFrame, 0, 0), self.center);
            if (isInHideArea && !_xxpk_hasTriggeredFeedback) {
                UIImpactFeedbackGenerator *feedback = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
                [feedback prepare]; // 提前准备震动，减少延迟
                [feedback impactOccurred];
                _xxpk_hasTriggeredFeedback = YES;
                
                // 使用UIView动画替代CATransaction，确保动画效果明显
                [UIView animateWithDuration:0.3
                                      delay:0
                                    options:UIViewAnimationOptionBeginFromCurrentState
                                 animations:^{
                    self.xxpk_hintView.transform = CGAffineTransformMakeScale(1.3, 1.3);
                } completion:nil];
            } else if (!isInHideArea) {
                if (_xxpk_hasTriggeredFeedback) {
                    self.xxpk_hintView.transform = CGAffineTransformMakeScale(1.2, 1.2);
                }
                _xxpk_hasTriggeredFeedback = NO;
            }
            
            // 更新隐藏标志
            touchArea = CGRectInset(hintFrame, 0, 0);
            _xxpk_shouldHide = CGRectContainsPoint(touchArea, self.center);
            break;
        }
            
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled: {
            // 使用单一动画隐藏提示视图
            [UIView animateWithDuration:0.3 animations:^{
                self.xxpk_hintView.alpha = 0.0;
                self.xxpk_hintView.transform = CGAffineTransformIdentity;
            }];
            
            if (_xxpk_shouldHide) {
                [XXGAlertView xxpk_showAlertWithTitle:nil message:XXGUIDriver.xxpk_string_ui.xxpk_floatview_hidetips buttonTitles:@[XXGUIDriver.xxpk_string_ui.xxpk_cancel, XXGUIDriver.xxpk_string_ui.xxpk_ok] completion:^(NSInteger buttonIndex) {
                    if (buttonIndex ==1) {
                        [self xxpk_privateHide];
                    }else {
                        [self xxpk_moveToNearestEdgeWithAnimation:YES];
                        [self xxpk_startAutoHideTimer];
                    }
                }];
            } else {
                [self xxpk_moveToNearestEdgeWithAnimation:YES];
                [self xxpk_startAutoHideTimer];
            }
            _xxpk_hasTriggeredFeedback = NO;
            _xxpk_isInHideArea = NO;
            break;
        }

        default: break;
    }
}

// 优化自动停靠动画
- (void)xxpk_moveToNearestEdgeWithAnimation:(BOOL)animate {
    if (!_xxpk_autoEdgeEnabled) return;
    
    // 如果已经在动画中，取消当前请求
    if (_xxpk_isAnimating && animate) return;
    
    CGRect safeFrame = [self xxpk_calculateSafeFrame];
    CGPoint center = self.center;
    
    CGFloat minX = safeFrame.origin.x;
    CGFloat maxX = safeFrame.origin.x + safeFrame.size.width;
    CGFloat minY = safeFrame.origin.y;
    CGFloat maxY = safeFrame.origin.y + safeFrame.size.height;
    
    // 计算最近边缘
    XXGFloatViewEdge targetEdge = XXGFloatViewEdgeNone;
    CGFloat minDistance = CGFLOAT_MAX;
    
    // 计算各边距离
    CGFloat toLeft = center.x - minX;
    CGFloat toRight = maxX - center.x;
    CGFloat toTop = center.y - minY;
    CGFloat toBottom = maxY - center.y;
    
    NSArray *distances = @[@(toLeft), @(toRight), @(toTop), @(toBottom)];
    NSArray *edges = @[@(XXGFloatViewEdgeLeft), @(XXGFloatViewEdgeRight),
                       @(XXGFloatViewEdgeTop), @(XXGFloatViewEdgeBottom)];
    
    for (NSInteger i = 0; i < distances.count; i++) {
        CGFloat distance = [distances[i] floatValue];
        if (distance < minDistance) {
            minDistance = distance;
            targetEdge = [edges[i] integerValue];
        }
    }
    
    // 如果目标边缘与当前边缘相同且位置接近，则不执行动画
    if (targetEdge == self.xxpk_currentEdge) {
        CGPoint currentCenter = self.center;
        CGPoint targetCenter = [self xxpk_calculateCenterForEdge:targetEdge];
        CGFloat distance = hypot(currentCenter.x - targetCenter.x, currentCenter.y - targetCenter.y);
        if (distance < 5.0) { // 如果距离很小，不执行动画
            return;
        }
    }
    
    self.xxpk_currentEdge = targetEdge;
    
    // 计算目标位置
    CGPoint targetCenter = [self xxpk_calculateCenterForEdge:targetEdge];
    CGPoint redotCenter = [self xxpk_calculateRedDotPositionForEdge:targetEdge];
    
    // 执行动画
    _xxpk_isAnimating = YES;
    
    // 使用CATransaction优化动画性能
    [CATransaction begin];
    [CATransaction setCompletionBlock:^{
        self->_xxpk_isAnimating = NO;
    }];
    
    [UIView animateWithDuration:animate ? 0.3 : 0
                     animations:^{
        self.center = targetCenter;
        self.xxpk_redDotView.center = redotCenter;
    }];
    
    [CATransaction commit];
}

// 新增：根据边缘计算中心点位置
- (CGPoint)xxpk_calculateCenterForEdge:(XXGFloatViewEdge)edge {
    CGRect safeFrame = [self xxpk_calculateSafeFrame];
    CGPoint center = self.center;
    
    CGFloat minX = safeFrame.origin.x;
    CGFloat maxX = safeFrame.origin.x + safeFrame.size.width;
    CGFloat minY = safeFrame.origin.y;
    CGFloat maxY = safeFrame.origin.y + safeFrame.size.height;
    
    CGPoint targetCenter = center;
    
    switch (edge) {
        case XXGFloatViewEdgeLeft:
            targetCenter.x = minX + self.bounds.size.width/2 + _xxpk_edgeInset;
            break;
        case XXGFloatViewEdgeRight:
            targetCenter.x = maxX - self.bounds.size.width/2 - _xxpk_edgeInset;
            break;
        case XXGFloatViewEdgeTop:
            targetCenter.y = minY + self.bounds.size.height/2 + _xxpk_edgeInset;
            break;
        case XXGFloatViewEdgeBottom:
            targetCenter.y = maxY - self.bounds.size.height/2 - _xxpk_edgeInset;
            break;
        default:
            break;
    }
    
    // 边界保护
    return [self xxpk_adjustedCenterForProposedCenter:targetCenter];
}

// 新增：根据边缘计算红点位置
- (CGPoint)xxpk_calculateRedDotPositionForEdge:(XXGFloatViewEdge)edge {
    CGPoint redotCenter = CGPointMake(0, 0);
    
    switch (edge) {
        case XXGFloatViewEdgeLeft:
            redotCenter.x = self.bounds.size.width;
            break;
        case XXGFloatViewEdgeRight:
            // 默认位置
            break;
        case XXGFloatViewEdgeTop:
            redotCenter.x = self.bounds.size.width;
            redotCenter.y = self.bounds.size.height;
            break;
        case XXGFloatViewEdgeBottom:
            redotCenter.x = self.bounds.size.width;
            break;
        default:
            break;
    }
    
    return redotCenter;
}

#pragma mark - 自动隐藏逻辑
- (void)xxpk_startAutoHideTimer {
    if (_xxpk_autoHideDelay <= 0) return;
    
    [self xxpk_cancelAutoHide];
    _xxpk_autoHideTimer = [NSTimer scheduledTimerWithTimeInterval:_xxpk_autoHideDelay
                                                     target:self
                                                   selector:@selector(xxpk_doAutoHide)
                                                   userInfo:nil
                                                    repeats:NO];
}

- (void)xxpk_cancelAutoHide {
    [_xxpk_autoHideTimer invalidate];
    _xxpk_autoHideTimer = nil;
}

- (void)xxpk_doAutoHide {
    [UIView animateWithDuration:0.3 animations:^{
        self.xxpk_iconView.alpha = 0.5;
        // 根据当前停靠方向进一步缩进
        CGRect frame = self.frame;
        switch (self.xxpk_currentEdge) {
            case XXGFloatViewEdgeLeft:
                frame.origin.x -= self.xxpk_edgeInset;
                break;
            case XXGFloatViewEdgeRight:
                frame.origin.x += self.xxpk_edgeInset;
                break;
            case XXGFloatViewEdgeTop:
                frame.origin.y -= self.xxpk_edgeInset;
                break;
            case XXGFloatViewEdgeBottom:
                frame.origin.y += self.xxpk_edgeInset;
                break;
            default:
                break;
        }
        self.frame = frame;
    }];
}

#pragma mark - 方向变化处理
- (void)xxpk_handleOrientationChange {
    [self xxpk_updateSafeArea];
    [self xxpk_updateHintViewLayout]; // 新增布局更新
    [self xxpk_moveToNearestEdgeWithAnimation:YES];
}

#pragma mark - 安全区域计算
- (void)xxpk_updateSafeArea {
    UIWindow *keyWindow = XXGWindowManager.shared.xxpk_currentWindow; //self.xxpk_hostKeyWindow;
    UIEdgeInsets safeArea = UIEdgeInsetsZero;
    if (![UIDevice hasNotch]) {
        safeArea = UIEdgeInsetsZero;
    }else if([UIDevice isIPad]) {
        safeArea = UIEdgeInsetsMake(0, 0, 20, 0);
    }else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
#pragma clang diagnostic pop
        safeArea = keyWindow.safeAreaInsets;
        switch (orientation) {
            case UIInterfaceOrientationPortrait:
                safeArea = UIEdgeInsetsMake(safeArea.top-10, 5, 15, 5);
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                safeArea = UIEdgeInsetsMake(15, 5, safeArea.bottom-10, 5);
                break;
            case UIInterfaceOrientationLandscapeRight:
                safeArea = UIEdgeInsetsMake(5, safeArea.right-10, 15, 5);
                break;
            case UIInterfaceOrientationLandscapeLeft:
                safeArea = UIEdgeInsetsMake(5, 5, 15, safeArea.left-10);
                break;
            case UIInterfaceOrientationUnknown:
            default:
                safeArea = safeArea;
        }
    }
    // 最终赋值给属性
    self.xxpk_safeAreaInsets = safeArea;
    self.xxpk_lastScreenBounds = keyWindow.bounds;
}

- (CGRect)xxpk_calculateSafeFrame {
    // 使用修正后的安全区域值
    return CGRectMake(
        self.xxpk_lastScreenBounds.origin.x + self.xxpk_safeAreaInsets.left,
        self.xxpk_lastScreenBounds.origin.y + self.xxpk_safeAreaInsets.top,
        self.xxpk_lastScreenBounds.size.width - (self.xxpk_safeAreaInsets.left + self.xxpk_safeAreaInsets.right),
        self.xxpk_lastScreenBounds.size.height - (self.xxpk_safeAreaInsets.top + self.xxpk_safeAreaInsets.bottom)
    );
}

#pragma mark - 其他优化
- (void)xxpk_resetToInitialPosition {
    NSString *centerString = [[NSUserDefaults standardUserDefaults] valueForKey:XXGUIDriver.xxpk_data_ui.xxpk_ui_FLOAT_CENTER];
    if (centerString) {
        self.center = CGPointFromString(centerString);
    }else {
        // 初始位置在右侧中间
        CGRect safeFrame = [self xxpk_calculateSafeFrame];
        self.center = CGPointMake(safeFrame.origin.x + safeFrame.size.width - self.bounds.size.width/2 - _xxpk_edgeInset,
                                  safeFrame.origin.y + safeFrame.size.height/2);
    }
}

#pragma mark - 辅助方法
- (UIWindow *)xxpk_findHostKeyWindow {
    if (@available(iOS 13.0, *)) {
        NSSet<UIScene *> *scenes = [UIApplication sharedApplication].connectedScenes;
        for (UIScene *scene in scenes) {
            if (scene.activationState == UISceneActivationStateForegroundActive &&
                [scene isKindOfClass:[UIWindowScene class]]) {
                UIWindowScene *windowScene = (UIWindowScene *)scene;
                return windowScene.windows.firstObject;
            }
        }
    }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    return [UIApplication sharedApplication].keyWindow;
#pragma clang diagnostic pop
}

- (CGPoint)xxpk_adjustedCenterForProposedCenter:(CGPoint)proposedCenter {
    CGRect safeFrame = [self xxpk_calculateSafeFrame];
    CGSize buttonSize = self.bounds.size;
    
    CGFloat minX = safeFrame.origin.x + buttonSize.width/2;
    CGFloat maxX = safeFrame.origin.x + safeFrame.size.width - buttonSize.width/2;
    CGFloat minY = safeFrame.origin.y + buttonSize.height/2;
    CGFloat maxY = safeFrame.origin.y + safeFrame.size.height - buttonSize.height/2;
    
    return CGPointMake(
        MAX(minX, MIN(proposedCenter.x, maxX)),
        MAX(minY, MIN(proposedCenter.y, maxY))
    );
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end
