//
//  KBFullAccessManager.m
//
//  统一封装“允许完全访问”检测：
//  1) 首选：反射调用 UIInputViewController 的 hasFullAccess（避免直接引用私有 API 标识）
//  2) 兜底：无法判断时返回 Unknown（上层可按需降级为 Denied 并提示）
//

#import "KBFullAccessManager.h"
#import <objc/message.h>
#if __has_include("KBNetworkManager.h")
#import "KBNetworkManager.h"
#endif
#if __has_include("KBKeyboardPermissionManager.h")
#import "KBKeyboardPermissionManager.h"
#endif

NSNotificationName const KBFullAccessChangedNotification = @"KBFullAccessChangedNotification";

@interface KBFullAccessManager ()
@property (nonatomic, weak) UIInputViewController *ivc;
@property (nonatomic, assign) KBFullAccessState state;
@end

@implementation KBFullAccessManager

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

- (instancetype)init {
    if (self = [super init]) {
        _state = KBFullAccessStateUnknown;
    }
    return self;
}

- (void)bindInputController:(UIInputViewController *)ivc {
    self.ivc = ivc;
    [self refresh];
}

- (KBFullAccessState)currentState { return _state; }

- (BOOL)hasFullAccess { return self.state == KBFullAccessStateGranted; }

- (void)refresh {
    KBFullAccessState newState = [self p_detectFullAccessState];
    if (newState != self.state) {
        self.state = newState;
        [[NSNotificationCenter defaultCenter] postNotificationName:KBFullAccessChangedNotification object:nil];
        [self p_applySideEffects];
    }
}

- (BOOL)ensureFullAccessOrGuideInView:(UIView *)parent {
    [self refresh];
    if (self.state == KBFullAccessStateGranted) return YES;
#if __has_include("KBFullAccessGuideView.h")
    // 动态引入，避免主 App 编译引用
    Class guideCls = NSClassFromString(@"KBFullAccessGuideView");
    if (guideCls && [guideCls respondsToSelector:NSSelectorFromString(@"showInView:")]) {
        SEL sel = NSSelectorFromString(@"showInView:");
        ((void (*)(id, SEL, UIView *))objc_msgSend)(guideCls, sel, parent);
    }
#endif
    return NO;
}

#pragma mark - Detect

// 通过反射调用 hasFullAccess（若系统提供），否则返回 Unknown
- (KBFullAccessState)p_detectFullAccessState {
    UIInputViewController *ivc = self.ivc;
    if (!ivc) return KBFullAccessStateUnknown;

    SEL sel = NSSelectorFromString(@"hasFullAccess");
    if ([ivc respondsToSelector:sel]) {
        BOOL granted = ((BOOL (*)(id, SEL))objc_msgSend)(ivc, sel);
        return granted ? KBFullAccessStateGranted : KBFullAccessStateDenied;
    }
    // 无法判断时标记 Unknown（上层可按需处理为未开启）
    return KBFullAccessStateUnknown;
}

#pragma mark - Side Effects

- (void)p_applySideEffects {
#if __has_include("KBNetworkManager.h")
    // 根据完全访问状态切换网络总开关
    [KBNetworkManager shared].enabled = (self.state == KBFullAccessStateGranted);
#endif
#if __has_include("KBKeyboardPermissionManager.h")
    // 上报给主 App：记录最近一次“完全访问”状态（App 将据此决定是否展示引导页）
    [[KBKeyboardPermissionManager shared] reportFullAccessFromExtension:(self.state == KBFullAccessStateGranted)];
#endif
}

@end
